【问题标题】:Event handling of an loaded assembly at run-time运行时加载程序集的事件处理
【发布时间】:2013-04-09 06:53:09
【问题描述】:

这是我试图从中学习的场景:

  • DLL 文件有时会引发事件。
  • DLL 文件无法添加到源代码中的引用,但它在磁盘上可用,并且程序可以在运行时访问它。
  • 我将 DLL 文件加载为运行时的程序集。
  • 我正在尝试从 DLL 订阅事件(我知道签名和参数格式),并在我的程序中处理它们。

Assembly 是一个简单的 Dll,其方法是添加其两个参数并使用包含求和运算结果的自定义参数引发事件。这是DLL的代码:

namespace Dll1
{
    public class Class1
    {
        public int c = 0;

        public void add(int a, int b)
        {
            c =  a + b;
            if (Added !=null)
                Added(this, new AddArgs(c));
        }

        public delegate void AddHandler(object sender, AddArgs e);

        public event AddHandler Added;

    }

    public class AddArgs : EventArgs
    {
        private int intResult;

        public AddArgs(int _Value) 
        {
            intResult = _Value;
        }

        public int Result
        {
            get { return intResult; }
        }
    }
}

然后,在我的程序中,我使用 Assembly.LoadFile 加载了该 DLL。我的程序中有另一个名为 EventProcessor 的类,它包含一个事件处理程序来处理来自已加载程序集的事件:

namespace ConsoleApplication1
{
    class Program
    {
        static Type[] parmTypes;

        static void Main(string[] args)
        {
            Assembly asm = Assembly.LoadFile(@"C:\Projects\Dll1.Dll");
            Type typ = asm.GetType("DLL1.Class1", true, true);

            var method = typ.GetMethod("add");
            EventInfo eInfo = typ.GetEvents()[0];
            var obj = Activator.CreateInstance(typ);

            EventProcessor evProc = new EventProcessor();
            Type myTypeObj = evProc.GetType();
            MethodInfo myMethodInfo = myTypeObj.GetMethod("myEventHandler");

            Delegate d = Delegate.CreateDelegate(myTypeObj, myMethodInfo, true); // Error!
            eInfo.AddEventHandler(obj, d);

            method.Invoke(obj, new object[] { 1, 0 });
        }
    }
}

但是,当运行程序时,我收到一条错误消息“类型必须从委托派生。 参数名称:类型“。我在这里做错了什么?或者有没有更好的方法来处理这种情况?如果有帮助,我还在最后添加了我的事件处理程序类。

namespace ConsoleApplication1
{
    class EventProcessor
    {
        public void myEventHandler(object sender, AddArgs args)
        {
            Console.WriteLine("Event Received.");
        }
    }

    public class AddArgs : EventArgs
    {
        private int intResult;

        public AddArgs(int _Value)
        {
            intResult = _Value;
        }

        public int Result
        {
            get { return intResult; }
        }
    }
}

提前致谢。

【问题讨论】:

    标签: c# reflection dll event-handling


    【解决方案1】:

    您的问题是 ConsoleApplication1 没有对 Dll1 的引用。即使您在两个程序集中的 AddArgs 结构相同,它们仍然是不同的类型,不能互换使用。

    解决方案是使用程序集ConsoleApplication1 和Dll1 都知道的类型。两个程序集必须使用相同的类型。

    您还使用了用于静态事件方法的 CreateDelegate 方法的覆盖。由于您正在尝试连接实例方法,因此您还必须提供目标。

    【讨论】:

    • 感谢您的解释和修改代码。我创建自定义事件参数的原因是我相信泛型 EventHandler 中的类型必须是 TEventArg 并且不能是“int”类型。实际上,使用 EventHandler 我得到了一个错误:类型“int”不能用作泛型类型或方法“System.EventHandler”中的类型参数“TEventArgs”。没有从“int”到“System.EventArgs”的装箱转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 2012-08-02
    • 2010-11-12
    • 1970-01-01
    • 2016-03-22
    相关资源
    最近更新 更多