C #: Создать событие, которое запускается всякий раз, когда запускается другое событие, имеющее слушателей, может быть, динамически с помощью отражения - PullRequest
2 голосов
/ 10 сентября 2010

Вот с чем я работаю:

Часть моего проекта - приложение для Windows. Я хочу в основном захватить каждое событие, которое запускает и имеет слушателей. Таким образом, событие нажатия какой-либо кнопки, событие проверки какого-либо флажка, все в основном списке событий «Управление». Так что это событие все еще срабатывает, но также и мое событие.

Имеется ли в моем распоряжении общее событие "сгенерированное какое-то событие", или я могу использовать рефлексию, чтобы перечислять все объекты в моей форме, анализировать все события, анализировать которых имеют прослушиватели, а затем подписать их всех на общее событие в другом месте в дополнение к тому, куда они уже идут?

Кто-нибудь знает, как это сделать?

Ответы [ 2 ]

4 голосов
/ 10 сентября 2010

Вы принципиально не можете сделать это: событие - это черный ящик с функциями «подписаться» и «отписаться».Таким образом, хотя вы можете использовать рефлексию, чтобы узнать все события, вы не можете надежно определить, на какие подписки были подписаны.Для событий, подобных полям, вы можете получить поле поддержки и проверить, является ли оно пустым, но даже если оно ненадежно - чтобы избежать проверок на пустое значение, автор мог написать что-то вроде этого:

public event EventHandler SomeEvent = delegate {};

Для другихсобытия, вам нужно будет решить, что на самом деле делает подписка на событие - например, оно может использовать EventHandlerList.

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

0 голосов
/ 10 сентября 2010

Не означает ли факт, что подписанное событие было инициировано, у него есть подписчик (и)?Итак, все, что вам нужно, это список подписываемых событий, которые вы можете проверить во время intercepted call.

. Вы можете перехватить вызов, используя любую AOP инфраструктуру.Например, используя Unity Interception, вы можете сделать что-то вроде этого:

public IMethodReturn Invoke(IMethodInvocation input, 
    GetNextHandlerDelegate getNext)
{
    // 1. assuming that you are keeping a list of method names 
    // that are being subscribed to.
    // 2. assuming that if the event is fired, then it must have
    // been subscribed to... 
    if (MyReflectedListOfSubscribedEvents.Contains(input.MethodBase.ToString())
    {
        HandleItSomeHow();
    }

    // process the call...
    return getNext().Invoke(input, getNext);
}
...