CreateDelegate上的绑定错误

时间:2013-01-23 15:17:25

标签: c# reflection delegates .net-assembly

我正在尝试将来自不同程序集的委托分配给从同一程序集加载的对象。

loader.LoadedGestures是一个对象[] - 其中的每个对象都来自不同的.dll。我希望该数组中的所有对象能够触发GestureDetected,定义如下。

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
    }
}

问题是每个.dll中都定义了GestureEventArgs和GestureEventHandler,否则它们将无法编译。我试图将GestureEventHandler作为在主类程序集中创建的对象附加,但是它避免在不同的程序集中有两个相同的对象类型......

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:2)

在多个程序集中定义GestureEventHandler / Args是一个严重的问题。你永远不会得到事件处理程序方法签名来匹配事件,.NET类型的标识包括它声明的程序集。在修复核心问题之前,这并没有好多少,只有一个程序集应该声明GestureEventHandler / Args,它应该被所有可以引发事件的程序集引用。和你的项目。

使用Reflection.Emit动态生成事件处理程序的代码是一种绝望的解决方案。

答案 1 :(得分:1)

如果我理解这一点,你就有以下结构

程序集1 - 定义GestureDetected Event和GestureEventArgs的版本。 程序集2 - 定义GestureDetected Event和GestureEventArgs的版本。 程序集3 - Dynamicaly会发现这些事件并尝试将它们连接到处理程序。

如果是这种情况,那么GestureEventArgs的哪个版本是程序集3引用的?

如果程序集3引用了程序集1中的GestureEventArgs版本,那么当for循环尝试从程序集2中挂钩事件时,您应该会遇到绑定异常(可以检查)

在不了解您想要设计的内容的情况下,我建议您可以通过创建一个公共库来解决这个问题,该库具有所有这些常见类型的定义并在所有dll中共享库(这将为您提供一个插件类型体系结构)