C# Использование отражения для подписки на события

0

Вопрос

У меня есть программа, в которой я использую отражение для динамической загрузки классов на основе текстового файла.

Когда я запускаю свой код, я могу выводить на экран все классы, методы и события и даже вызывать методы.

Я добавил все события в словарь и хочу перечислить их, а затем создать обработчик событий, чтобы получить данные, отправленные событием.

вот мой метод для занесения событий в словарь:

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

если я распечатаю Словарь, я смогу увидеть события по ключу и значению.

но я, похоже, не могу создать обработчик событий. Я перепробовал множество вариантов, включая:

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");
                     }                      



                 }

я пытаюсь подписаться на событие и обработать данные в другом классе с именем "DisplayChangeEvents".

я пытался в течение 2 дней получить это, и это последняя часть, которая мне нужна, чтобы программа работала должным образом.

Заранее спасибо

основываясь на предложении, я обновил код в цикле 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));                               
                        //}

                    }

получите следующее исключение:

Указанное приведение недопустимо.

класс, создающий события, выглядит следующим образом:

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

событие, которое запускает событие, выглядит следующим образом:

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

эта логика работает во всех других программах, за исключением тех случаев, когда я пытаюсь динамически создавать классы.

c# event-handling events reflection
2021-11-19 17:49:46
1

Лучший ответ

0

Я последовал совету здешних людей, сократил свой код и вернулся к основам с обработчиками событий. Я смог загрузить драйверы в свой код с помощью отражения и вызвать участников, однако мне не удалось заставить события работать так, как я думал. Я смог просто добавить переключатель и посмотреть, какие драйверы были загружены и подписаны на события вручную. Не идеально, но если бы эта группа не сказала мне сократить расходы и вернуться к основам, я бы никогда не зашел так далеко, как зашел. Спасибо вам всем

2021-12-08 17:52:33

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................