/// <summary> /// Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder /// when invoked. /// </summary> public static Delegate GenerateHandler(Type eventSignature, IEventRecorder recorder) { Type returnType = GetDelegateReturnType(eventSignature); Type[] parameters = GetDelegateParameterTypes(eventSignature); var eventHandler = new DynamicMethod( eventSignature.Name + "DynamicHandler", returnType, AppendParameterListThisReference(parameters), recorder.GetType() .Module); MethodInfo methodToCall = typeof(IEventRecorder).GetMethod("RecordEvent", BindingFlags.Instance | BindingFlags.Public); ILGenerator ilGen = eventHandler.GetILGenerator(); // Make room for the one and only local variable in our function ilGen.DeclareLocal(typeof(object[])); // Create the object array for the parameters and store in local var index 0 ilGen.Emit(OpCodes.Ldc_I4, parameters.Length); ilGen.Emit(OpCodes.Newarr, typeof(Object)); ilGen.Emit(OpCodes.Stloc_0); for (var index = 0; index < parameters.Length; index++) { // Push the object array onto the evaluation stack ilGen.Emit(OpCodes.Ldloc_0); // Push the array index to store our parameter in onto the evaluation stack ilGen.Emit(OpCodes.Ldc_I4, index); // Load the parameter ilGen.Emit(OpCodes.Ldarg, index + 1); // Box value-type parameters if (parameters[index] .IsValueType) { ilGen.Emit(OpCodes.Box, parameters[index]); } // Store the parameter in the object array ilGen.Emit(OpCodes.Stelem_Ref); } // Push the this-reference on the stack as param 0 for calling the handler ilGen.Emit(OpCodes.Ldarg_0); // Push the object array onto the stack as param 1 for calling the handler ilGen.Emit(OpCodes.Ldloc_0); // Call the handler ilGen.EmitCall(OpCodes.Call, methodToCall, null); ilGen.Emit(OpCodes.Ret); return(eventHandler.CreateDelegate(eventSignature, recorder)); }
/// <summary> /// Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder /// when invoked. /// </summary> public static Delegate GenerateHandler(Type eventSignature, IEventRecorder recorder) { Type returnType = GetDelegateReturnType(eventSignature); Type[] parameters = GetDelegateParameterTypes(eventSignature); var eventHandler = new DynamicMethod( eventSignature.Name + "DynamicHandler", returnType, AppendParameterListThisReference(parameters), recorder.GetType() .Module); MethodInfo methodToCall = typeof (IEventRecorder).GetMethod("RecordEvent", BindingFlags.Instance | BindingFlags.Public); ILGenerator ilGen = eventHandler.GetILGenerator(); // Make room for the one and only local variable in our function ilGen.DeclareLocal(typeof (object[])); // Create the object array for the parameters and store in local var index 0 ilGen.Emit(OpCodes.Ldc_I4, parameters.Length); ilGen.Emit(OpCodes.Newarr, typeof (Object)); ilGen.Emit(OpCodes.Stloc_0); for (var index = 0; index < parameters.Length; index++) { // Push the object array onto the evaluation stack ilGen.Emit(OpCodes.Ldloc_0); // Push the array index to store our parameter in onto the evaluation stack ilGen.Emit(OpCodes.Ldc_I4, index); // Load the parameter ilGen.Emit(OpCodes.Ldarg, index + 1); // Box value-type parameters if (parameters[index] .IsValueType) { ilGen.Emit(OpCodes.Box, parameters[index]); } // Store the parameter in the object array ilGen.Emit(OpCodes.Stelem_Ref); } // Push the this-reference on the stack as param 0 for calling the handler ilGen.Emit(OpCodes.Ldarg_0); // Push the object array onto the stack as param 1 for calling the handler ilGen.Emit(OpCodes.Ldloc_0); // Call the handler ilGen.EmitCall(OpCodes.Call, methodToCall, null); ilGen.Emit(OpCodes.Ret); return eventHandler.CreateDelegate(eventSignature, recorder); }