CreateProvider(Control control, string eventName) { // // Dynamically create inherited class that is strongly typed // for the event handler. // EventInfo ei = control.GetType().GetEvent(eventName); EventBroadcastProvider broadcastProvider = CreateHandlerForEvent(ei); broadcastProvider.Bind(control, eventName); return(broadcastProvider); }
/// <summary> /// Returns a derived instance of <see cref="EventBroadcastProvider"/> that /// matches the types required by the targeted event handler. /// </summary> /// <param name="ei"></param> /// <returns></returns> private static EventBroadcastProvider CreateHandlerForEvent(EventInfo ei) { EventBroadcastProvider result = null; string namespaceName = typeof(EventBroadcastProvider).Namespace; string eventName = ei.Name; string className = eventName + "BroadcastProvider"; AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = className + "Assembly"; AppDomain appDomain = AppDomain.CurrentDomain; AssemblyBuilder assBuilder = appDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder modBuilder = assBuilder.DefineDynamicModule(className + "Module"); TypeBuilder typBuilder = modBuilder.DefineType(className, TypeAttributes.Public, typeof(EventBroadcastProvider)); FieldBuilder fldBuilder = typBuilder.DefineField("m_handler", typeof(Delegate), FieldAttributes.Private); ILGenerator ilGen = null; // // Build the RelayDelegate property. // PropertyBuilder relayDelegateBuilder = typBuilder.DefineProperty("RelayDelegate", PropertyAttributes.None, typeof(Delegate), null); MethodBuilder get_relayDelegateBuilder = typBuilder.DefineMethod("get_RelayDelegate", MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Family | MethodAttributes.SpecialName, typeof(Delegate), null); ilGen = get_relayDelegateBuilder.GetILGenerator(); ilGen.DeclareLocal(typeof(Delegate)); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldfld, fldBuilder); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Ret); relayDelegateBuilder.SetGetMethod(get_relayDelegateBuilder); // // Build the HandleEvent method. // MethodBuilder handleEventBuilder = typBuilder.DefineMethod("HandleEvent", MethodAttributes.Private | MethodAttributes.HideBySig, null, new Type[] { typeof(object), ei.EventHandlerType.GetMethod("Invoke").GetParameters()[1].ParameterType }); ilGen = handleEventBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, typeof(EventBroadcastProvider).GetMethod("Relay", BindingFlags.Instance | BindingFlags.NonPublic)); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Ret); // // Build the constructor. // ConstructorBuilder ctorBuilder = typBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, null); ilGen = ctorBuilder.GetILGenerator(); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldnull); ilGen.Emit(OpCodes.Stfld, fldBuilder); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Call, typeof(EventBroadcastProvider). GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldftn, handleEventBuilder); ilGen.Emit(OpCodes.Newobj, ei.EventHandlerType.GetConstructors()[0]); ilGen.Emit(OpCodes.Stfld, fldBuilder); ilGen.Emit(OpCodes.Nop); ilGen.Emit(OpCodes.Ret); result = (EventBroadcastProvider)Activator. CreateInstance(typBuilder.CreateType()); return(result); }