I'm trying to write a class that's to be used to trigger a call to a method from an arbitrary event but I'm stuck as I simply cannot figure out a way to reference 'this' from emitted MSIL code.
This example should describe what I'm looking for:
class MyEventTriggeringClass
{
private object _parameter;
public void Attach(object source, string eventName, object parameter)
{
_parameter = parameter;
var e = source.GetType().GetEvent(eventName);
if (e == null) return;
hookupDelegate(source, e);
}
private void hookupDelegate(object source, EventInfo e)
{
var handlerType = e.EventHandlerType;
// (omitted some validation here)
var dynamicMethod = new DynamicMethod("invoker",
null,
getDelegateParameterTypes(handlerType), // (omitted this method in this exmaple)
GetType());
var ilgen = dynamicMethod.GetILGenerator();
var toBeInvoked = GetType().GetMethod(
"invokedMethod",
BindingFlags.NonPublic | BindingFlags.Instance);
ilgen.Emit(OpCodes.Ldarg_0); // <-- here's where I thought I could push 'this' (failed)
ilgen.Emit(OpCodes.Call, toBeInvoked);
ilgen.Emit(OpCodes.Ret);
var sink = dynamicMethod.CreateDelegate(handlerType);
e.AddEventHandler(source, sink);
}
private void invokedMethod()
{
Console.WriteLine("Value of _parameter = " + _parameter ?? "(null)");
// output is always "(null)"
}
}
Here's an xample how I envision the class being used:
var handleEvent = new MyEventTriggeringClass();
handleEvent.Attach(someObject, "SomeEvent", someValueToBePassedArround);
(Please note that the above example is quite pointless. I just try to describe what I'm looking for. My final goal here is to be able to trigger a call to an arbitrary method whenever an arbitrary event fires. I'll use that in a WPF projekt where I try to use 100% MVVM but I've stumbled upon one of the [seemingly] classic breaking points.)
Anyway, the code "works" so far as it successfully invoked the "invokedMethod" when the arbitrary event fires but 'this' seems to be an empty object (_parameter is always null). I have done some research but simply cannot find any good examples where 'this' is properly passed to a method being called from within a dynamic method like this.
The closest example I've found is THIS ARTICLE but in that example 'this' can be forced to the dynamic method since it's called from the code, not an arbitrary event handler.
Any suggestions or hints would be very appreciated.
I'm gonna go ahead and answer my own question here. The solution was very simple once I realized what the real problem was: Specifying the event handler's instance/target. This is done by adding an argument to MethodInfo.CreateDelegate().
If you're interested, here's a simple example you can cut'n'paste into a console app and try it out:
So, thanks for your comments and help. Hopefully someone learned something. I know I did.
Cheers