Here's what I am working with:
Part of my project is a windows form app. I want to basically capture every event that fires and has listeners. So some button's click event, some checkbox's check event, everything on a basic "Contro开发者_如何学Cl" event list. So that event still fires, but also fires my event.
Is there a generic "some event fired" event under the hood I can tap into, or is there a way using reflection to enumerate through all objects in my form, parse out all the events, parse which have listeners, and then subscribe all of them to a generic event elsewhere in addition to where they are already going?
Anyone know how to do this?
You fundamentally can't do this: an event is a black box with just "subscribe" and "unsubscribe" functionality. So while you can use reflection to find out all the events, you can't reliably detect which have been subscribed to. For field-like events you could fetch the backing field and check whether or not it's null, but even that's not reliable - to avoid null checks, the author may have written something like this:
public event EventHandler SomeEvent = delegate {};
For other events, you'd have to work out what subscribing to the event actually does - for example, it might use EventHandlerList
.
Basically, you should rethink your design so you don't need to do this.
Doesn't the fact that a subscribed event got fired indicate it has subscriber(s)? So then all you would need is a list of subscribable events, which you can validate against during an intercepted call
.
You can intercept a call using any AOP
framework. For instance, by using Unity Interception
, you can do something like this:
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);
}
精彩评论