I am using reflection to add an event handler to an event :
var eventInfo = type.GetEvent(eventName);
MethodInfo mi = GetType().GetMethod("TestMethod",
BindingFlags.Instance | BindingFlags.NonPublic);
var delegateForMethod = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, mi);
eventInfo.AddEventHandler(this, delegateForMethod);
This successfully calls my test method when the event occurs which is great, but now I need to know the name of the event that ended up calling this method...
void TestMethod(object sender, EventArgs e)
{
// I know the sender, but which event was fired on the sender?
}
The reason I need this is because I have this generic register method which hooks up handlers to different types, and different events and channels them all to one method, while also making a note of what was attached. Once the test method fires, I need to pull out that note and use the info to notify the correct object that their "desired" event has fired. -- but to know this I need to know the event name as well as the type.
For example, in register I added Event A in type X for object O.... now when I see it triggered in the test method, I need to know it was Event A in type X, so I can notify object O by a certain interface method on it.
There is no problem that canot be solved by introducing an additional level of abstraction!
Bind event like this:
obj.SomeEvent += (sender, args) => TestMethod("SomeEvent", sender, args);
or by reflection:
var eventInfo = type.GetEvent(eventName);
EventHandler delegateForMethod = (o, args) => TestMethod(eventInfo.Name, o, args);
eventInfo.AddEventHandler(this, delegateForMethod);
And in handler you can access event name from parameter:
void TestMethod(string eventName, object sender, EventArgs e)
{
// eventName is event was fired on the sender
TestMethod(sender, e);
}
Crazy thinking here.
To every event you are going to add TestMethod
, before TestMethod
you add an anonimous method
, wich I will call SetEventName
for understanding purposes.
That SetEventName
just sets some GlobalEventName
variable in your class taking eventName
. (I suppose there's a way to use a lambda expression for that).
So, every time the event is fired. SetEventName
is called.
Your GlobalEventName
is set. Then TestMethod
is called.
And inside TestMethod
, use the GlobalEventName
to do your job.
See an idea (sorry, I don't understand reflection quite well to put a ready-to-use code, but that's the idea)
var eventInfo = type.GetEvent(eventName);
Action<object, EventArgs> SetEventName = (Ob, Args) => GlobalEventName = eventName;
//I really don't know if it would work but....
Add that to the eventInfo before adding the TestMethod.
MethodInfo mi = GetType().GetMethod("TestMethod",
BindingFlags.Instance | BindingFlags.NonPublic);
var delegateForMethod = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, mi);
eventInfo.AddEventHandler(this, delegateForMethod);
And your testmethod:
void TestMethod(object sender, EventArgs e)
{
//Use the GlobalEventName to get event's name.
// I know the sender, but which event was fired on the sender?
}