mercredi 12 août 2020

How to read the implementation class in default interface method?

I want to create a default interface method that can respond with the annotated value of the implementation class.

Example: in the following, I want all Child implementations to read their own @Generated value field:

public interface Parent {
    default String[] find() {
        return AnnotationUtils.findAnnotation(this.getClass(), Generated.class).value();
    }
}

@Generated(value = {"test"})
public class Child implements Parent {

}

Usage:

System.out.println(new Child().find());

Result: NullPointerException, because the call tries to find the annotation on the Parent interface class, not the implementation class.

It it still possible somehow?





could not load or find assembly Microsoft.Azure.cosmos.table

I have a windows forms application WinFormsProj, which references a class library project named ModelsProj.
ModelsProj has dependency to Microsoft.Azure.Cosmos.Table version 1.0.7.0.
At runtime, when WinFormsProj reaches this code, raises a FileNotFoundException saying that could not load or find assemble Microsoft.Azure.Cosmos.Table`:

var entityTypes = typeof(EntityBase).Assembly.GetExportedTypes()
            .Where(t => t.GetInterface(typeof(IDto).FullName) == null
                        && t.GetInterface(typeof(IEntity).FullName) != null && !t.IsAbstract);

EntityBase is the base type of all of my model entities, and is located in ModelProj.

I can solve the exception by just adding a reference to Microsoft.Azure.Cosmos.Table in WinFormsProj.
However, I expect the program work without doing this! My question is : Why isn't the dll of Microsoft.Azure.Cosmos.Table getting copied to the output? Isn't the build process supposed to put all the needed dlls in output directory?

I've found here that a common cause is that a project and one if its dependencies, depend on different versions of the same package. That is not my case, WinFormsProj does not need to reference any version of Microsoft.Azure.Cosmos.Table itself!


further info: I've used fuslogvw.exe to inspect what happens and here is its log:

*** Assembly Binder Log Entry  (8/12/2020 @ 10:25:22 AM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  H:\melkradar-git\melkradar\src\MelkRadar\Mgmt\MelkRadar.Mgmt.Win\bin\Debug\MelkRadar.Mgmt.Win.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Microsoft.Azure.Cosmos.Table, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///H:/melkradar-git/melkradar/src/MelkRadar/Mgmt/MelkRadar.Mgmt.Win/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = MelkRadar.Mgmt.Win.exe
Calling assembly : MelkRadar.Core.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: H:\melkradar-git\melkradar\src\MelkRadar\Mgmt\MelkRadar.Mgmt.Win\bin\Debug\MelkRadar.Mgmt.Win.exe.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Microsoft.Azure.Cosmos.Table, Version=1.0.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///H:/melkradar-git/melkradar/src/MelkRadar/Mgmt/MelkRadar.Mgmt.Win/bin/Debug/Microsoft.Azure.Cosmos.Table.DLL.
LOG: Attempting download of new URL file:///H:/melkradar-git/melkradar/src/MelkRadar/Mgmt/MelkRadar.Mgmt.Win/bin/Debug/Microsoft.Azure.Cosmos.Table/Microsoft.Azure.Cosmos.Table.DLL.
LOG: Attempting download of new URL file:///H:/melkradar-git/melkradar/src/MelkRadar/Mgmt/MelkRadar.Mgmt.Win/bin/Debug/Microsoft.Azure.Cosmos.Table.EXE.
LOG: Attempting download of new URL file://

BTW, I've tried cleaning the solution, restarting VS, rebuilding and trying again, suggested in similar questions. it didn't work.





mardi 11 août 2020

Is the argument of breaking SINGLETON pattern with REFLECTION practical?

I learned about SINGLETON to be implemented through enums, so that, it retains the singleton nature against reflection also.

Can there be a practical industry/realTime scenario, where such thing could happen ?

My understanding is NO.

When all the code is with me, why will I have such a thing happen to any singleton class at my code.

Rather, such code practice, would be visible to those having access to code repository, so it wont skip the eyes !

Asking to understand, if I am missing some perspective, through which this could actually happen !





Using Reflection to get a collection property in generic type variable c# [duplicate]

I have my classes structure like below:

public abstract class base
{
    public ICollection<Attachment> Files { get; set; }
}

public class a : base
{
    public string Status { get; set; }
    public bool Shared { get; set; }
    public bool Urgent { get; set; }
}

public class a : base
{
    public string Status { get; set; }
    public bool Shared { get; set; }
    public bool Urgent { get; set; }
}

in my method I use generic argument which is like below, entity argument can be type a or b how can I access to Files property in my entity, I use reflection to get it and it gets the Files but it doesnt let me to loop into it.

    public virtual async Task<TEntity> CreateAsync(TEntity entity)
    {
       Type t = entity.GetType();
       var files = t.GetProperty("Files").GetValue(entity);

       //I want to loop into the file variable above
       foreach (var item in files)
       {
          //some code
       }
    }




Java reflection invoke on getDeclaringClass

I have a interface like this and some classes implemented this interface:

public interface MyInterface {}
public class Informations implements MyInterface {

    @Command("version")
    public void getVersion() {
        System.out.println("1.0-SNAPSHOT");
    }
}

public class Systems implements MyInterface {

    @Command("os")
    public void getOs() {
        System.out.println("Linux OS");
    }
}      

I collecting all methods annotated @Command in a Map like this :

/* String is command */ 
private Map<String, Method> commandMaps = new ConcurrentHashMap<>();  

Now , I want invoke this methods :

Optional<String> optionalCommand = commandMaps.keySet().stream().filter(e -> e.equals(user_input_command)).findFirst();
if (optionalCommand.isPresent()) {
    Method method = commandMaps.get(optionalCommand.get());
    Class<?> declaringClass = method.getDeclaringClass();
    System.out.println(">> " + method.getName());
    System.out.println(">> " + declaringClass.getName());
    method.invoke(declaringClass);
}

for example user enter os command and declaringClass.getName() referenced to Systems class but can not invoking declaringClass . so , this code result IllegalArgumentException exception :

>> getOs
>> a.b.c.Systems
java.lang.IllegalArgumentException: object is not an instance of declaring class      

How can fix this problem ?





Using reflection to get all classes that implement a interface and only initialise class that matches ID/opcode given

So in the following code, there is a Instruction interface that is used by a number of classes such as AddInstruction, DivideInstruction and so on. Each of the classes that implements the interface assignes a label and opcode as per the Instruction interface.

Instruction.cs

public abstract class Instruction
    {
        private string label;
        private string opcode;

        protected Instruction(string label, string opcode)
        {
            this.label = label;
            this.opcode = opcode;
        }

        public abstract void Execute(Machine m);
    }

Example of one of the many instructions all of which have the same basic functionalities

AddInstruction.cs

public class AddInstruction : Instruction
    {
        
        private int reg, s1, s2;

        public AddInstruction(string lab, int reg, int s1, int s2) : base(lab, "add") // here the base interface is Instruction and we are assigning the opcode as add, other instructions have there own opcodes //
        {
            this.reg = reg;
            this.s1 = s1;
            this.s2 = s2;
        }

        public override void Execute(Machine m) =>
            // do something
}

From here I want to use the factory pattern along with Reflection to make it so in the future new instructions with there own opcodes can be initiated based on the opcode provided.

InstructionFactoryInterface.cs

interface InstructionFactoryInterface
    {
        Instruction GetInstruction(string opcode);
    }

InstructionFactory.cs

class InstructionFactory : InstructionFactoryInterface
    {
        public Instruction GetInstruction(string opcode)
        {
            Type type = typeof(Instruction);
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(s => s.GetTypes())
                .Where(p => type.IsAssignableFrom(p));
            foreach (var type1 in types)
            {
                // loop through all the types and only return the class that has a matching opcode //
            }
   }

Now here is where i am suck, how can i loop through all the types that implement the Instruction interface and only return the type that matches the opcode parameter passed in. Thank you





Static context is null after been set

This .Net Core 3.1 (NUnit 3) test works under Visual Studio 2019.

But as soon I use JetBrains Rider the test fails because the static property (DataA) returns null in mostly all contexts.

Has some a idea what goes wrong and how to solve this issue?

public static class ClassA
{
    public static string DataA { get; set; }
    public static string DataB { get; set; }
    
    public static void SetAppConfig(string appSettingsPfad)
    {
        IList<JProperty> appSettings = JsonConvert.DeserializeObject<JToken>(appSettingsPfad).Select(j => (JProperty)j).ToList();

        var appKonfiguration = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.Static);

        foreach (JProperty property in appSettings)
        {
            var appKonfigurationProperty = appKonfiguration.SingleOrDefault(p => p.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase));
            var value = ((JValue)property.Value).Value;

            if (appKonfigurationProperty != null)
                appKonfigurationProperty.SetValue(null, Convert.ChangeType(value, appKonfigurationProperty.PropertyType));
        }
    }
}

[TestFixture]
public class DummyTest
{
    [Test]
    public void TestA()
    {
        LoadAppConfig();
        
        // DataA returns null here
        Console.WriteLine(ClassA.DataA);
        
        new BusinessLogicClass.DoSomething();
        // [...]
    }
    
    private void LoadAppConfig() {
        // [...]
        string appSettings = File.ReadAllText(jsonConfigFiles.Single());
        ClassA.SetAppConfig(appSettings);
        
        // here it works and a result is the proper string
        Console.WriteLine(ClassA.DataA);
        // [...]
    }
}

public class BusinessLogicClass {
    
    public void DoSomething() {
        // DataA returns null here
        Console.WriteLine(ClassA.DataA);
        // [...]
    }
}

(I have simplfied this code to the bare minimum, the orginal code would run into a Exception after a null check)