mardi 17 octobre 2017

Getting repeated fields via inheritance with GetFields()

I have a problem while working with GetFields() method while trying to get all the fields from a user defined class.

I have a parent class with, lets say two public fields, and another class that inherits from the parent and overrides one of the parent fields with the new keyword.

Problem comes when I use the GetFields method with the second class, because it's returning all the fields, including the overriden one. Is there something that I am doing wrong or a solution for only getting in this case the GoodBye field from the Parent class and the only one Hello field, the one from the inherited class?

This is a simple example of what I'm saying:

    public class Foo
    {
        public string Hello = "sdfsafda";

        public string GoodBye = string.Empty;
    }


    public class Bar : Foo
    {
        public new string Hello = "jl";
    }


    static void Main(string[] args)
    {

        var a = new Bar();



        var derp = new List<string>();

        foreach (var fieldInfo in a.GetType().GetFields())
        {

            derp.Add(fieldInfo.Name);

        }

        Console.WriteLine(derp.Count);
        // writes 3 instead of 2

    }

About using Properties instead of Fields, I'm afraid I can't use them right now because of limitations that are not in my hand to solve in the project I'm working on.





lundi 16 octobre 2017

Types from Assembly.GetExportedTypes do not show interfaces from other assembly

I've got a solution that has three projects. In the first project, I've got a library that exports an interface type named IHandler. In the second project, I've got a library that exports a class that subscribes to the IHandler interface from the first project. In the third and final project, I've got a console application that loads the second project, at run-time, and creates an instance of the mentioned class.

I'm trying to add some code to the third project, the console app, that makes sure that the class from the second project actually subscribes to IHandler. To do this, I've got the following code ...

public static IHandler Load(string path)
{
    var absolute = Path.GetFullPath(path);

    var library = Assembly.LoadFile(absolute);

    foreach (var type in library.GetExportedTypes())
    {
        if (type.GetInterface(typeof(IHandler).FullName) == null)
        {
            continue;
        }

        return Activator.CreateInstance(type) as IHandler;
    }
}

So, this code runs inside my console project. It loads my library project and makes sure the exported type subscribes to the IHandler interface. The IHandler interface is from a third project.

The problem is that every method I try of checking the interfaces on the exported class of mine, that does subscribe to IHandler, shows that the type has no interfaces. I can't seem to ensure that my loaded type has the interface it needs.

Any ideas?





Reflection Help Needed: GetProperty Returns Unexpected Type

I am working with the .NET PropertyGrid object. At runtime, I need to inspect the Label property for the PropertyGrid's PropertyGridView.SelectedGridEntry object.

The first problem is that SelectedGridEntry is not a public property--it appears to be internal. So I needed to resort to reflection. I believe I successfully obtained a PropertyGridView instance object using this simple line of code:

var gridView = PropertyGrid.Controls[2];

(Let's accept for the dubious assumption that the PropertyGridView object always is available at PropertyGrid.Controls1.)

Reflection aside for the moment, I used the Visual Studio 2017 debugger at runtime to inspect the PropertyGrid's PropertyGridView object. Here is the image of that:

enter image description here

This image shows that the gridView object has a property called SelectedGridEntry. Notice its type is System.Windows.Forms.PropertyGridInternal.PropertyDescriptorGridEntry. Unfortunately, I cannot cast to the PropertyDescriptorGridEntry type because I cannot get access to the System.Windows.Forms.PropertyGridInternal namespace (Microsoft doesn't make that available, it seems).

In an effort to obtain the SelectedGridEntry object, I used this line of code:

var selectedGridEntry = PropertyGrid.Controls[2].GetType().GetProperty("SelectedGridEntry", BindingFlags.Instance | BindingFlags.NonPublic);

Unfortunately, this returns a var of type GridEntry:

enter image description here

I don't understand why the type obtained through reflection isn't the expected PropertyDescriptorGridEntry type. And since I can't seem to gain access to the namespace I need, I can't cast the GridEntry object to a PropertyDescriptorGridEntry object.

How can I assign a local variable to the SelectedGridEntry object and ensure it's the correct PropertyDescriptorGridEntry type? I feel if I succeed in doing that, I then can obtain that object's Label property value...





Run Bluebird.reflect() on a regular promise

I need to reflect the promise of this function so that I always get a resolved promise, even if the underlying result of the promise was rejected, because I need to check dependency services' status upon server lift. If the dependency service is running well - return true, otherwise return false but do not reject/fail the promise, thus the whole process.

I've tried these two ways:

const logServerPromise = new Bluebird((resolve, reject) => {
  return ping.promise.probe(logServerHost)
    .then((result) => {
      return resolve(result);
    })
    .catch((err) => {
      return reject(err);
    });
});

logServerPromise.reflect();

and

Bluebird.promisifyAll(ping.promise);

ping.promise.probeAsync().reflect();

In the first case it works well when the dependency is running, but when it's not - I get an exception with the usual error when it's not running, instead of the promise being handled by reflect().

In the second case it hangs no matter the status of the dependency.

Any idea how I can wrap/handle this?





Updating field attributes by annotation

I'm reviewing how reflection works or possible work. I have this SomeClassBuilder wherein it has an attribute target : Target with declared annotation TargetAnnotation.

Thing is, is it possible to override/update the values/properties of Target wherein upon invoke of someMethod() would return the paramters on the annotation?

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface TargetAnnotation {
    String first();
    String second();
    // other attributes
}

public class Target {
    String first;
    String second;
    // some other attributes unique only to `Target`
}

public interface TargetHelper {
    void setTarget(Target target)''
}

public class SomeClassBuilder implements TaretHelper {

    @TargetAnnotation(first = "first", second = "second")
    private Target target;

    @Override public void setTarget(Target target) { this.target = target }

    public void someMethod() {
        System.out.println(target.first); // should be `first`
        System.out.println(target.first); // should be `second`
    }

}





Overwrite Object properties with properties of other Object using reflection

Im trying to do something that might seem a bit unorthodox, however this is due to some limitations in a framework that im using.

Basically my case is this: 1: I have an object that has several fields, all with default values. 2: I have an other object that is initialized and has all values that I want to have, in the new object.

Im trying to do this with reflection, so looping over all public setMethods, finding all getMethods that seem to be matching from the other object, invoking them and invoke the other setMethod with the value over the invoked setMethod.

This is what I came up with so far:

java.lang.reflect.Method[] publicMethods1 = newlabels.getClass().getMethods();
                        for(int i=0; i<publicMethods1.length; i++){
                            if (publicMethods1[i].getName().startsWith("set")){
                                String setname = publicMethods1[i].getName();
                                String getname = "get"+setname.substring(3, setname.length());
                                try {
                                    java.lang.reflect.Method getMethod = labels.getClass().getMethod(getname, null);
                                    publicMethods1[i].invoke(newlabels, getMethod.invoke(labels, null));
                                } catch (NoSuchMethodException e1) {
                                    //System.out.println("Couldnot find a method with name: "+getname);
                                } catch (SecurityException e1) {
                                    //System.out.println("Security exception occured");
                                } catch (IllegalAccessException e1) {
                                    //System.out.println("IllegalAccessException");
                                } catch (IllegalArgumentException e1) {
                                    //System.out.println("IllegalArgumentException");
                                } catch (InvocationTargetException e1) {
                                    //System.out.println("InvocationTargetException");
                                }
                            }
                        }

This unfortunately isn't working, its not giving errors either (unless a getter wasnt found, but ill take that). I looked around on the internet and found somewhat similar in this method:

/**
 * Only works for methods with equally named getters and setters
 * 
 * 1. Get all declared methods of obj1 and find all setters
 * 2. Get all declared methods of obj2 and find all getters
 * 3. Find which setter belongs to which getter
 * 4. Set the value of obj1.setter with obj2.getter 
 * 
 * @param obj1
 * @param obj2
 */
public static void runAllSettersWithGetters(Object obj1, Object obj2) {
    ArrayList<Method> setters = findSetters(obj1);
    ArrayList<Method> getters = findGetters(obj2);

    for(int s=0; s<setters.size(); s++){
        String setmethodname = setters.get(s).getName();
        String whattoset = setmethodname.substring(3);
        for(int g=0; g<getters.size(); g++){
            boolean isboolean = false;
            boolean match = false;
            if(getters.get(g).getReturnType().equals(Boolean.TYPE)){
                isboolean = true;
            }

            String getmethodname = getters.get(g).getName();
            String whattoget = getmethodname.substring(3);
            if(whattoset.equalsIgnoreCase(whattoget)){
                match = true;
            }else{
                //might start with is instead of get
                whattoget = getmethodname.substring(2);
                if(whattoset.equalsIgnoreCase(whattoget)){
                    match = true;
                }
            }

            if(match){
                try {
                    setters.get(s).invoke(obj1, getters.get(g).invoke(obj2));
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

So I tried it, because it seems better, however in the end it gives the same not working solution.

Can anyone help me with this?





dimanche 15 octobre 2017

kotlin reflection for java method accepting null Class array

I have java code like this:

 Method m = device.getClass()
        .getMethod("removeBond", (Class[]) null);
    m.invoke(device, (Object[]) null);

and i am trying to write the same thing in kotlin like this:

device.javaClass.getMethod("removeBondNative", null as Class<*>).invoke(device, null as Any)

but i get this error message:

Process: com.example.zemcd.toofxchange, PID: 17466
                                                                           kotlin.TypeCastException: null cannot be cast to non-null type java.lang.Class<*>
                                                                               at com.example.zemcd.toofxchange.BluetoothUtils$Companion.unPair(BluetoothUtils.kt:61)
                                                                               at com.example.zemcd.toofxchange.DeviceAdapter$DeviceHolder$bindItems$1$$special$$inlined$forEach$lambda$1.onClick(DeviceAdapter.kt:98)
                                                                               at android.view.View.performClick(View.java:5217)
                                                                               at android.view.View$PerformClick.run(View.java:21349)
                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5585)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

i also tried changing null to Unit:

device.javaClass.getMethod("removeBondNative", Unit as Class<*>).invoke(device, null as Any)

but still encounter error:

Process: com.example.zemcd.toofxchange, PID: 19219
                                                                           java.lang.ClassCastException: kotlin.Unit cannot be cast to java.lang.Class
                                                                               at com.example.zemcd.toofxchange.BluetoothUtils$Companion.unPair(BluetoothUtils.kt:61)
                                                                               at com.example.zemcd.toofxchange.DeviceAdapter$DeviceHolder$bindItems$1$$special$$inlined$forEach$lambda$1.onClick(DeviceAdapter.kt:98)
                                                                               at android.view.View.performClick(View.java:5217)
                                                                               at android.view.View$PerformClick.run(View.java:21349)
                                                                               at android.os.Handler.handleCallback(Handler.java:739)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                               at android.os.Looper.loop(Looper.java:148)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5585)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

what i am doing wrong here? how can java reflection be mirrored in kotlin in a situation like this?