sjdebdaly
sjdebdaly

Reputation: 3

Binding error on CreateDelegate

I'm having a fun time trying to assign a delegate from a different assembly to an object which has been loaded from the same assembly.

loader.LoadedGestures is an object[] - each object in it comes from a different .dll. I want all of the objects within that array to be able to trigger GestureDetected, defined below.

public class Foo
{
    private void Initialise_Gestures()
    {
        loader = new GestureLoader();

        loader.LoadGestures(); // load all the Gestures into the array

        for (int i = 0; i < loader.LoadedGestures.Length; i++)
        {
            if (loader.LoadedGestures[i] != null)
            {
                EventInfo ev = loader.LoadedGestures[i].GetType().GetEvent("GestureDetected");
                Type del = ev.EventHandlerType;
                MethodInfo mi = this.GetType().GetMethod("GestureDetected", BindingFlags.NonPublic | BindingFlags.Instance);

                Delegate d = Delegate.CreateDelegate(del, this, mi); // <- "Error binding to target method."

                ev.AddEventHandler(loader.LoadedGestures[i], d);
            }
        }
    }



    private void GestureDetected(object sender, GestureEventArgs e)
    {
        // do stuff
    }
}

The problem is that GestureEventArgs and GestureEventHandler are defined in each of the .dlls, or they won't compile. I've tried to attach the GestureEventHandler as an object created within the main class' assembly, but it moans that there are two of the same object types in different assemblies...

Any help would be appreciated.

Upvotes: 0

Views: 249

Answers (2)

Hans Passant
Hans Passant

Reputation: 941665

Having GestureEventHandler/Args defined in more than one assembly is a crippling problem. You'll never get the event handler method signature to match the event, the identity of a .NET type includes the assembly it was declared in. This doesn't get much better until you fix the core problem, only one assembly should declare GestureEventHandler/Args and it should be referenced by all assemblies that can raise the event. And your project.

Dynamically generating the code for the event handler with Reflection.Emit is a desperation solution.

Upvotes: 2

Sam Vemagiri
Sam Vemagiri

Reputation: 119

If I understood this right, you have the following structure

Assembly 1 - Defines a version of GestureDetected Event and GestureEventArgs. Assembly 2 - Defines a version of GestureDetected Event and GestureEventArgs. Assembly 3 - Dynamicaly dicovers these events and tries to hook them up to a handler.

If that is the case, which version of GestureEventArgs is Assembly 3 referencing to?

If Assembly 3 is referencing to a version of GestureEventArgs from Assembly 1, you should expect to get binding exception when the for loop tries to hook the event from Assembly 2 (you can check this)

Without knowing too much of what you are trying to design, I suggest you could solve this problem by creating a common library that has all these common types defined and share the library across all the dlls (this will give you a plugin type architecture)

Upvotes: 1

Related Questions