예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }