简体   繁体   English

C# 使用反射订阅事件

[英]C# Using Reflection to subscribe to Events

I have a program where i am using Reflection to load classes dynamically based on a text file.我有一个程序,我在其中使用反射基于文本文件动态加载类。

When i run my code i can get all the classes, methods and Events printing to screen and can even Invoke the methods.当我运行我的代码时,我可以将所有类、方法和事件打印到屏幕上,甚至可以调用这些方法。

I added all events to a Dictionary and i want to enumerate through them and then create a Event Handler to get the data sent by the event.我将所有事件添加到字典中,我想通过它们进行枚举,然后创建一个事件处理程序来获取事件发送的数据。

here is my method for getting the events to a dictionary:这是我将事件写入字典的方法:

 private Dictionary<string, EventInfo> RetrieveEvents(string label, string type)
    {
        try
        {
            this.displaysAssembly = Assembly.LoadFrom(Path.Combine(Directory.GetApplicationDirectory(), "Framework.DisplayDrivers.dll"));

            string assembly = string.Format("Framework.DisplayDrivers.{0}", type);
            Type cswitcher = displaysAssembly.GetType(assembly);

            fullClass = cswitcher;
            Dictionary<string, EventInfo> ekvp = new Dictionary<string, EventInfo>();
            List<EventInfo> eventInfos = cswitcher.GetEvents().Where(e => HasInformationAttribute(e)).ToList();

            foreach (var e in eventInfos)
            {                   
                if (!ekvp.ContainsKey(label))
                {
                    ekvp.Add(e.Name, e);
                }

            }

            return (ekvp);
        }
        catch (MissingMethodException e)
        {
            ErrorLog.Error(LogHeader + "Unable to create Display. No constructor: {0}", e.Message);
        }
        catch (ArgumentException e)
        {
            ErrorLog.Error(LogHeader + "Unable to create Display. No type: {0}", e.Message);
        }
        catch (NullReferenceException e)
        {
            ErrorLog.Error(LogHeader + "Unable to create Display. No match: {0}", e.Message);
        }


        return null;
    }

if I print out the Dictionary i can see the events by Key and Value.如果我打印出字典,我可以按键和值查看事件。

but i cannot seem to create an Event handler.但我似乎无法创建事件处理程序。 I have tried many options including:我尝试了很多选择,包括:

foreach(var evnt in d._projectors._events)
                 {
                     EventInfo ev = evnt.Value;


                     try
                     {

                         // this id not work
                         object classInstance = Activator.CreateInstance(d._projectors.fullClass);
                         ev.AddEventHandler(classInstance, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));

                         // this did not work either

                         if (d._projectors._events.TryGetValue("OnPowerStateRecieved", out ev))
                         {
                             ev.AddEventHandler(ev.Name, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));                               
                         }

                     }
                     catch (Exception ex)
                     {

                         ErrorLog.Error("Error creating event handers :  " +  ex.Message + "\r");
                     }                      



                 }

i am trying to subscibe to the event and handle the data in another class named "DisplayChangeEvents".我正在尝试订阅该事件并处理另一个名为“DisplayChangeEvents”的 class 中的数据。

i have been trying for 2 days to get this and its the last piece i need to get the program working as expected.我已经尝试了 2 天来得到这个,这是我需要让程序按预期工作的最后一块。

Thanks in advance提前致谢

based on a suggestion i updated the code in the foreach loop to:根据一个建议,我将 foreach 循环中的代码更新为:

 foreach(var evnt in d._projectors._events)
                {
                    EventInfo ev = evnt.Value;


                    try
                    {

                        if (evnt.Key == "OnPowerStateRecieved")
                        {
                            ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));
                        }
                        else if (evnt.Key == "OnMuteStateRecieved")
                        {
                            ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));
                        }
                        // this id not work
                        // object classInstance = Activator.CreateInstance(d._projectors.fullClass);
                        //  ev.AddEventHandler(classInstance, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));

                        //ev.AddEventHandler(d._projectors.fullClass, new EventHandler(DisplayChangeEvents.DisplayMuteChangedEvent));

                        //// this did not work either

                        //if (d._projectors._events.TryGetValue("OnPowerStateRecieved", out ev))
                        //{
                        //    ev.AddEventHandler(ev.Name, new EventHandler(DisplayChangeEvents.DisplayPowerChangedEvent));                               
                        //}

                    }

get the following exception:得到以下异常:

Specified cast is not valid.指定的演员表无效。

the class that is creating the events looks like this:创建事件的 class 如下所示:

 private static event EventHandler<PowerStateEventsArgs> _onPowerStateRecieved = delegate { };
    [Information(Description = "Power Event")]

    public static event EventHandler<PowerStateEventsArgs> OnPowerStateRecieved
    {
        add
        {
            if (!_onPowerStateRecieved.GetInvocationList().Contains(value))
            {
                 _onPowerStateRecieved += value;
            }
        }
        remove
        {
            _onPowerStateRecieved -= value;
        }
    }

the event that fires the event looks like this:触发事件的事件如下所示:

 if (i == 1)
                {
                    _onPowerStateRecieved(null, new PowerStateEventsArgs(true));
                }

this logic works in all other programs except when i am trying to reflection to create the classes dynamically.此逻辑适用于所有其他程序,除非我尝试反射以动态创建类。

I took the advice of the folks here and cut back my code and went back to basics with event handlers.我听取了这里的人的建议,减少了我的代码,回到了事件处理程序的基础上。 I was able to load the drivers in my code via reflection and invoke the members, However I was unable to get the events working the way that I thought they would.我能够通过反射在我的代码中加载驱动程序并调用成员,但是我无法让事件以我认为的方式工作。 I was able to just add in a switch-case and see which drivers were loaded and subscribed to the events manually.我可以添加一个 switch-case 并查看哪些驱动程序已手动加载和订阅事件。 Not ideal but if this group had not told me to cut back and go back to basics I would never have gotten as far as I did.不理想,但如果这个小组没有告诉我削减开支并且 go 回到基础,我永远不会达到我所做的那样。 Thank you all谢谢你们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM