public void SetRaiseMethod_PInvokeImplMethod_Twice()
        {
            TypeBuilder   type         = Helpers.DynamicType(TypeAttributes.Abstract);
            EventBuilder  eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method       = type.DefineMethod("TestMethod", MethodAttributes.PinvokeImpl);

            eventBuilder.SetRaiseMethod(method);
            eventBuilder.SetRaiseMethod(method);
        }
Exemplo n.º 2
0
        public void TestOnAbstractMethod()
        {
            EventBuilder  ev     = TypeBuilder.DefineEvent("Event_PosTest1", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method = TypeBuilder.DefineMethod("Method_PosTest1", MethodAttributes.Abstract | MethodAttributes.Virtual);

            ev.SetRaiseMethod(method);

            // add this method again
            ev.SetRaiseMethod(method);
        }
Exemplo n.º 3
0
        public void TestOnPInvokeMethod()
        {
            EventBuilder  ev     = TypeBuilder.DefineEvent("Event_PosTest4", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method = TypeBuilder.DefineMethod("Method_PosTest4", MethodAttributes.PinvokeImpl);

            ev.SetRaiseMethod(method);

            // add this method again
            ev.SetRaiseMethod(method);
        }
        public void SetRaiseMethod_StaticMethod_Twice()
        {
            TypeBuilder   type         = Helpers.DynamicType(TypeAttributes.Abstract);
            EventBuilder  eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method       = type.DefineMethod("TestMethod", MethodAttributes.Static);
            ILGenerator   ilGenerator  = method.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ret);

            eventBuilder.SetRaiseMethod(method);
            eventBuilder.SetRaiseMethod(method);
        }
Exemplo n.º 5
0
        public void TestOnStaticMethod()
        {
            byte[] bytes = new byte[MethodBodyLength];
            _generator.GetBytes(bytes);
            EventBuilder  ev     = TypeBuilder.DefineEvent("Event_PosTest3", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method = TypeBuilder.DefineMethod("Method_PosTest3", MethodAttributes.Static);
            ILGenerator   ilgen  = method.GetILGenerator();

            ilgen.Emit(OpCodes.Ret);

            ev.SetRaiseMethod(method);

            // add this method again
            ev.SetRaiseMethod(method);
        }
        private void BuildEvent(DynamicType type, EventDefinition eventDefinition)
        {
            EventBuilder eventBuilder = type.DefineEvent(eventDefinition.Name,
                                                         (System.Reflection.EventAttributes)eventDefinition.Attributes,
                                                         ResolveType(eventDefinition.EventType));

            // TODO: Custom modifiers and other stuff.

            if (eventDefinition.InvokeMethod != null)
            {
                eventBuilder.SetRaiseMethod(BuildMethod(type, eventDefinition.InvokeMethod));
            }
            if (eventDefinition.AddMethod != null)
            {
                eventBuilder.SetAddOnMethod(BuildMethod(type, eventDefinition.AddMethod));
            }
            if (eventDefinition.RemoveMethod != null)
            {
                eventBuilder.SetRemoveOnMethod(BuildMethod(type, eventDefinition.RemoveMethod));
            }

            metadataPass.Add(delegate
            {
                InitializeCustomAttributes(eventBuilder.SetCustomAttribute, eventDefinition.CustomAttributes);
            });
        }
Exemplo n.º 7
0
        /// <summary>
        /// Implements an interface event in a duck proxy type using a given type builder.
        /// If successful, the implemented event will be added to the given proxy member dictionary.
        /// </summary>
        /// <param name="proxyType">Type builder for the duck proxy type.</param>
        /// <param name="proxyMembers">Dictionary of members of the proxy type.</param>
        /// <param name="duckField">Field that holds a reference to the duck object to forward calls to.</param>
        /// <param name="interfaceEvent">The interface event to implement.</param>
        private void ImplementEvent(TypeBuilder proxyType, ProxyMemberDictionary proxyMembers, FieldInfo duckField, EventInfo interfaceEvent)
        {
            EventInfo duckEvent = FindDuckEvent(interfaceEvent);

            if (duckEvent == null)
            {
                throw new NotImplementedException("Duck type does not implement an event named \"" + interfaceEvent.Name + "\" with the same event handler type.");
            }

            EventBuilder proxyEvent = proxyType.DefineEvent(interfaceEvent.Name, EventAttributes.None, interfaceEvent.EventHandlerType);

            // Associated methods appear before the event in the member array; thus, they have already been
            // defined and implemented.  The proxy member dictionary is used to refer to these.
            proxyEvent.SetAddOnMethod((MethodBuilder)(proxyMembers[duckEvent.GetAddMethod()]));
            proxyEvent.SetRemoveOnMethod((MethodBuilder)(proxyMembers[duckEvent.GetRemoveMethod()]));
            proxyEvent.SetRaiseMethod((MethodBuilder)(proxyMembers[duckEvent.GetRaiseMethod()]));
            MethodInfo[] otherDuckMethods = duckEvent.GetOtherMethods();
            foreach (MethodInfo otherDuckMethod in otherDuckMethods)
            {
                if (proxyMembers.ContainsKey(otherDuckMethod))
                {
                    proxyEvent.AddOtherMethod((MethodBuilder)(proxyMembers[otherDuckMethod]));
                }
            }

            // Add proxy event to the proxy member dictionary
            // (This is not really necessary, but good to keep things consistent)
            // proxyMembers.Add(duckEvent, proxyEvent);
            // For some reason, EventBuilder does not inherit MemberInfo, so it cannot be added.
        }
        public void SetRaiseMethod_NullMethod_ThrowsArgumentNullException()
        {
            TypeBuilder  type         = Helpers.DynamicType(TypeAttributes.Abstract);
            EventBuilder eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler));

            AssertExtensions.Throws <ArgumentNullException>("mdBuilder", () => eventBuilder.SetRaiseMethod(null));
        }
Exemplo n.º 9
0
        private static MethodBuilder ImplementOnPropertyChanged(TypeBuilder typeBuilder, FieldBuilder field,
                                                                EventBuilder eventInfo)
        {
            var methodBuilder = typeBuilder.DefineMethod("OnPropertyChanged",
                                                         MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig |
                                                         MethodAttributes.NewSlot, typeof(void),
                                                         new[] { typeof(string) });
            var generator        = methodBuilder.GetILGenerator();
            var returnLabel      = generator.DefineLabel();
            var propertyArgsCtor = typeof(PropertyChangedEventArgs).GetConstructor(new[] { typeof(string) });

            generator.DeclareLocal(typeof(PropertyChangedEventHandler));
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, field);
            generator.Emit(OpCodes.Stloc_0);
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Brfalse, returnLabel);
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Newobj, propertyArgsCtor);
            generator.Emit(OpCodes.Callvirt, typeof(PropertyChangedEventHandler).GetMethod("Invoke"));
            generator.MarkLabel(returnLabel);
            generator.Emit(OpCodes.Ret);
            eventInfo.SetRaiseMethod(methodBuilder);
            return(methodBuilder);
        }
        public void SetRaiseMethod_MultipleDifferentMethods()
        {
            TypeBuilder   type         = Helpers.DynamicType(TypeAttributes.Abstract);
            EventBuilder  eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method1      = type.DefineMethod("PInvokeMethod", MethodAttributes.PinvokeImpl);
            MethodBuilder method2      = type.DefineMethod("InstanceMethod", MethodAttributes.Public);
            ILGenerator   ilGenerator  = method2.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ret);
            MethodBuilder method3 = type.DefineMethod("StaticMethod", MethodAttributes.Static);
            MethodBuilder method4 = type.DefineMethod("AbstractMethod", MethodAttributes.Abstract | MethodAttributes.Virtual);

            eventBuilder.SetRaiseMethod(method1);
            eventBuilder.SetRaiseMethod(method2);
            eventBuilder.SetRaiseMethod(method3);
            eventBuilder.SetRaiseMethod(method4);
        }
Exemplo n.º 11
0
        public void TestOnMultipleDifferentMethods()
        {
            byte[] bytes = new byte[MethodBodyLength];
            _generator.GetBytes(bytes);

            EventBuilder  ev      = TypeBuilder.DefineEvent("Event_PosTest5", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method1 = TypeBuilder.DefineMethod("PMethod_PosTest5", MethodAttributes.PinvokeImpl);
            MethodBuilder method2 = TypeBuilder.DefineMethod("IMethod_PosTest5", MethodAttributes.Public);
            ILGenerator   ilgen   = method2.GetILGenerator();

            ilgen.Emit(OpCodes.Ret);
            MethodBuilder method3 = TypeBuilder.DefineMethod("SMethod_PosTest5", MethodAttributes.Static);
            MethodBuilder method4 = TypeBuilder.DefineMethod("AMethod_PosTest5", MethodAttributes.Abstract | MethodAttributes.Virtual);

            ev.SetRaiseMethod(method1);
            ev.SetRaiseMethod(method2);
            ev.SetRaiseMethod(method3);
            ev.SetRaiseMethod(method4);
        }
        public void SetRaiseMethod_TypeCreated_ThrowsInvalidOperationException()
        {
            TypeBuilder   type         = Helpers.DynamicType(TypeAttributes.Abstract);
            EventBuilder  eventBuilder = type.DefineEvent("TestEvent", EventAttributes.None, typeof(TestEventHandler));
            MethodBuilder method       = type.DefineMethod("TestMethod", MethodAttributes.Abstract | MethodAttributes.Virtual);

            type.CreateTypeInfo().AsType();

            Assert.Throws <InvalidOperationException>(() => eventBuilder.SetRaiseMethod(method));
        }
Exemplo n.º 13
0
        public static void Invoke_Event_Add_And_Remove_And_Raise_Invokes_Correct_Methods()
        {
            // C# cannot emit raise_Xxx method for the event, so we must use System.Reflection.Emit to generate such event.
            AssemblyBuilder ab   = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("EventBuilder"), AssemblyBuilderAccess.Run);
            ModuleBuilder   modb = ab.DefineDynamicModule("mod");
            TypeBuilder     tb   = modb.DefineType("TestType_IEventService", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract);
            EventBuilder    eb   = tb.DefineEvent("AddRemoveRaise", EventAttributes.None, typeof(EventHandler));

            eb.SetAddOnMethod(tb.DefineMethod("add_AddRemoveRaise", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, typeof(void), new Type[] { typeof(EventHandler) }));
            eb.SetRemoveOnMethod(tb.DefineMethod("remove_AddRemoveRaise", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, typeof(void), new Type[] { typeof(EventHandler) }));
            eb.SetRaiseMethod(tb.DefineMethod("raise_AddRemoveRaise", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, typeof(void), new Type[] { typeof(EventArgs) }));
            TypeInfo ieventServiceTypeInfo = tb.CreateTypeInfo();

            List <MethodInfo> invokedMethods = new List <MethodInfo>();
            object            proxy          =
                typeof(DispatchProxy)
                .GetRuntimeMethod("Create", Array.Empty <Type>()).MakeGenericMethod(ieventServiceTypeInfo.AsType(), typeof(TestDispatchProxy))
                .Invoke(null, null);

            ((TestDispatchProxy)proxy).CallOnInvoke = (method, args) =>
            {
                invokedMethods.Add(method);
                return(null);
            };

            EventHandler handler = new EventHandler((sender, e) => {});

            proxy.GetType().GetRuntimeMethods().Single(m => m.Name == "add_AddRemoveRaise").Invoke(proxy, new object[] { handler });
            proxy.GetType().GetRuntimeMethods().Single(m => m.Name == "raise_AddRemoveRaise").Invoke(proxy, new object[] { EventArgs.Empty });
            proxy.GetType().GetRuntimeMethods().Single(m => m.Name == "remove_AddRemoveRaise").Invoke(proxy, new object[] { handler });

            Assert.True(invokedMethods.Count == 3, String.Format("Expected 3 method invocations but received {0}", invokedMethods.Count));

            EventInfo eventInfo = ieventServiceTypeInfo.GetDeclaredEvent("AddRemoveRaise");

            Assert.NotNull(eventInfo);

            MethodInfo expectedMethod = eventInfo.AddMethod;

            Assert.True(invokedMethods[0] != null && expectedMethod == invokedMethods[0], String.Format("First invoke should have been {0} but actual was {1}",
                                                                                                        expectedMethod.Name, invokedMethods[0]));

            expectedMethod = eventInfo.RaiseMethod;
            Assert.True(invokedMethods[1] != null && expectedMethod == invokedMethods[1], String.Format("Second invoke should have been {0} but actual was {1}",
                                                                                                        expectedMethod.Name, invokedMethods[1]));

            expectedMethod = eventInfo.RemoveMethod;
            Assert.True(invokedMethods[2] != null && expectedMethod == invokedMethods[2], String.Format("Third invoke should have been {0} but actual was {1}",
                                                                                                        expectedMethod.Name, invokedMethods[1]));
        }
Exemplo n.º 14
0
        public void TestThrowsExceptionOnCreateTypeCalled()
        {
            try
            {
                EventBuilder  ev     = TypeBuilder.DefineEvent("Event_NegTest2", EventAttributes.None, typeof(TestEventHandler));
                MethodBuilder method = TypeBuilder.DefineMethod("Method_NegTest2", MethodAttributes.Abstract | MethodAttributes.Virtual);
                TypeBuilder.CreateTypeInfo().AsType();

                Assert.Throws <InvalidOperationException>(() => { ev.SetRaiseMethod(method); });
            }
            finally
            {
                _typeBuilder = null;
            }
        }
Exemplo n.º 15
0
        public void TestCreation()
        {
            eb = tb.DefineEvent("event2", EventAttributes.SpecialName, typeof(AnEvent));

            eb.SetRaiseMethod(mb);
            eb.SetAddOnMethod(mb);
            eb.SetRemoveOnMethod(mb);
            eb.AddOtherMethod(mb);
            eb.AddOtherMethod(mb);

            Type t = tb.CreateType();

            MethodInfo mi = t.GetMethod("OnAnEvent");

            EventInfo[] events = t.GetEvents();
            Assert.AreEqual(2, events.Length);

            {
                EventInfo ev = t.GetEvent("event1");
                Assert.AreEqual("event1", ev.Name);
                Assert.AreEqual(EventAttributes.None, ev.Attributes);
                Assert.AreEqual(t, ev.DeclaringType);

                Assert.AreEqual(typeof(AnEvent), ev.EventHandlerType);
                Assert.AreEqual(true, ev.IsMulticast);
                Assert.AreEqual(false, ev.IsSpecialName);

                Assert.AreEqual(mi, ev.GetAddMethod());
                Assert.AreEqual(null, ev.GetRaiseMethod());
                Assert.AreEqual(mi, ev.GetRemoveMethod());
            }

            {
                EventInfo ev = t.GetEvent("event2");
                Assert.AreEqual("event2", ev.Name);
                Assert.AreEqual(EventAttributes.SpecialName, ev.Attributes);
                Assert.AreEqual(t, ev.DeclaringType);

                Assert.AreEqual(typeof(AnEvent), ev.EventHandlerType);
                Assert.AreEqual(true, ev.IsMulticast);
                Assert.AreEqual(true, ev.IsSpecialName);

                Assert.AreEqual(mi, ev.GetAddMethod());
                Assert.AreEqual(mi, ev.GetRaiseMethod());
                Assert.AreEqual(mi, ev.GetRemoveMethod());
            }
        }
Exemplo n.º 16
0
        private static MethodBuilder ImplementOnPropertyChangedHelper(TypeBuilder typeBuilder, FieldBuilder field,
                                                                      EventBuilder eventInfo)
        {
            var methodBuilder = typeBuilder.DefineMethod("OnPropertyChanged",
                                                         MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig |
                                                         MethodAttributes.NewSlot, CallingConventions.Standard | CallingConventions.HasThis, typeof(void),
                                                         new[] { typeof(string) });
            var generator   = methodBuilder.GetILGenerator();
            var returnLabel = generator.DefineLabel();

            generator.DeclareLocal(typeof(PropertyChangedEventHandler));
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, field);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Call, typeof(PropertyChangedInvoker).GetMethod("Invoke"));
            generator.MarkLabel(returnLabel);
            generator.Emit(OpCodes.Ret);
            eventInfo.SetRaiseMethod(methodBuilder);
            return(methodBuilder);
        }
    // Create the callee transient dynamic assembly.
    private static TypeBuilder CreateCallee(AppDomain myDomain)
    {
        AssemblyName assemblyName = new AssemblyName();

        assemblyName.Name = "EmittedAssembly";

        // Create the callee dynamic assembly.
        AssemblyBuilder myAssembly =
            myDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
        // Create a dynamic module named "CalleeModule" in the callee.
        ModuleBuilder myModule = myAssembly.DefineDynamicModule("EmittedModule");

        // Define a public class named "HelloWorld" in the assembly.
        TypeBuilder helloWorldClass =
            myModule.DefineType("HelloWorld", TypeAttributes.Public);

        MethodBuilder myMethod1 = helloWorldClass.DefineMethod("OnClick",
                                                               MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) });
        ILGenerator methodIL1 = myMethod1.GetILGenerator();

        methodIL1.Emit(OpCodes.Ret);
        MethodBuilder myMethod2 = helloWorldClass.DefineMethod("OnMouseUp",
                                                               MethodAttributes.Public, typeof(void), new Type[] { typeof(Object) });
        ILGenerator methodIL2 = myMethod2.GetILGenerator();

        methodIL2.Emit(OpCodes.Ret);

        // Create the events.
        EventBuilder myEvent1 = helloWorldClass.DefineEvent("Click", EventAttributes.None,
                                                            typeof(MyEvent));

        myEvent1.SetRaiseMethod(myMethod1);
        EventBuilder myEvent2 = helloWorldClass.DefineEvent("MouseUp", EventAttributes.None,
                                                            typeof(MyEvent));

        myEvent2.SetRaiseMethod(myMethod2);

        helloWorldClass.CreateType();
        return(helloWorldClass);
    }
Exemplo n.º 18
0
        public static T CreateType <T>() where T : class           //Generic class'ın tanımlanması
        {
            var name = new AssemblyName("MyProxies");
            //Asembly oluşturabilmek için önce bir AssemblyName denen kimlik kartı benzeri bir yapı oluşturulmalı.
            //Bu AssemblyName basit bir isme, versiyon numarasına ve şifreleme anahtarlarına sahip olmalı.
            //Bu yapıyı oluşturmak için ise AssemblyName fonksiyonu kullanıyoruz

            var assembly = AssemblyBuilder.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
            //Bir assembly oluşturuyoruz. Assembly ise module denen yapıları tutan bir başka yapı


            var ModuleYaratici = assembly.DefineDynamicModule("MyProxies");

            //Bir moduler oluşturuyoruz. Modüller derlenmiş il kodu tutan yapılar. ör:dll dosyaları
            var TipYaratici = ModuleYaratici.DefineType("MyPersonProxy", TypeAttributes.Class | TypeAttributes.Public, typeof(T));

            bool MyClassAttribute = typeof(T).GetCustomAttribute <ImplementPropertyErisildiAttribute>() != null;                                                      //Girdi olarak alınan sınıfın attribute'ünün kontrol edilmesi
            bool NotifyPropertyErisildiAttribute      = typeof(T).GetProperties().Where(x => x.GetCustomAttribute <NotifyPropertyErisildiAttribute>() != null).Any(); //Sınıfın Property'lerinin attribute'lerinin kontrol edilmesi
            bool DoNotNotifyPropertyErisildiAttribute = false;

            if (MyClassAttribute == false && NotifyPropertyErisildiAttribute == false) //Hem sınıfta hemde barındırdığı property'lerde bizim attribute yok ise
            {
                return(Activator.CreateInstance <T>());                                // sınıfa kod enjekte edilmeyeceği için sınıfın işlem görmeden yaratılması
            }
            TipYaratici.AddInterfaceImplementation(typeof(INotifyPropertyErisildi));   //MyPersonProxy sınıfına Interface'in uygulanması

            //Event oluşturmak için bir EventBuilder oluşturuyoruz tipi "PropertyGetEventHandler"
            EventBuilder eventBuilder = TipYaratici.DefineEvent("PropertyErisildi", EventAttributes.ReservedMask | EventAttributes.RTSpecialName | EventAttributes.SpecialName, typeof(PropertyErisildiEventHandler));
            //Bir FieldBuilder oluşturuyluyor PropertyGetEventHandler tipinde.
            FieldBuilder eventField = TipYaratici.DefineField("PropertyErisildi", typeof(PropertyErisildiEventHandler), FieldAttributes.Private);


            //event in add methodu
            var eventAddMethod = TipYaratici.DefineMethod("add_PropertyErisildi",
                                                          MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                                                          CallingConventions.Standard | CallingConventions.HasThis, typeof(void), new[] { typeof(PropertyErisildiEventHandler) });
            var addEventIL = eventAddMethod.GetILGenerator();
            var combine    = typeof(Delegate).GetMethod("Combine", new[] { typeof(Delegate), typeof(Delegate) });

            addEventIL.Emit(OpCodes.Ldarg_0);
            addEventIL.Emit(OpCodes.Ldarg_0);
            addEventIL.Emit(OpCodes.Ldfld, eventField);
            addEventIL.Emit(OpCodes.Ldarg_1);
            addEventIL.Emit(OpCodes.Call, combine);
            addEventIL.Emit(OpCodes.Castclass, typeof(PropertyErisildiEventHandler));
            addEventIL.Emit(OpCodes.Stfld, eventField);
            addEventIL.Emit(OpCodes.Ret);
            eventBuilder.SetAddOnMethod(eventAddMethod);

            //event in remove methodu
            var removeMethod = TipYaratici.DefineMethod("remove_PropertyErisildi",
                                                        MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                                                        CallingConventions.Standard | CallingConventions.HasThis, typeof(void), new[] { typeof(PropertyErisildiEventHandler) });
            var remove        = typeof(Delegate).GetMethod("Remove", new[] { typeof(Delegate), typeof(Delegate) });
            var removeEventIL = removeMethod.GetILGenerator();

            removeEventIL.Emit(OpCodes.Ldarg_0);
            removeEventIL.Emit(OpCodes.Ldfld, eventField);
            removeEventIL.Emit(OpCodes.Ldarg_1);
            removeEventIL.Emit(OpCodes.Call, remove);
            removeEventIL.Emit(OpCodes.Castclass, typeof(PropertyErisildiEventHandler));
            removeEventIL.Emit(OpCodes.Stfld, eventField);
            removeEventIL.Emit(OpCodes.Ret);
            eventBuilder.SetRemoveOnMethod(removeMethod);

            //Before get
            var methodBuilder = TipYaratici.DefineMethod("BeforeGet", MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, typeof(void), new[] { typeof(string) });
            var generator     = methodBuilder.GetILGenerator();
            var returnLabel   = generator.DefineLabel();
            var eventArgsCtor = typeof(PropertyChangedEventArgs).GetConstructor(new[] { typeof(string) });

            generator.DeclareLocal(typeof(PropertyErisildiEventHandler));
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldfld, eventField);
            generator.Emit(OpCodes.Stloc_0);
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Brfalse, returnLabel);
            generator.Emit(OpCodes.Ldloc_0);
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Newobj, eventArgsCtor);
            generator.Emit(OpCodes.Callvirt, typeof(PropertyChangedEventHandler).GetMethod("Invoke"));
            generator.MarkLabel(returnLabel);
            generator.Emit(OpCodes.Ret);
            eventBuilder.SetRaiseMethod(methodBuilder);

            foreach (var item in typeof(Person).GetProperties())
            {
                if (MyClassAttribute == true)
                {
                    DoNotNotifyPropertyErisildiAttribute = item.GetCustomAttribute <DontNotifyPropertyErisildiAttribute>() != null;
                    if (DoNotNotifyPropertyErisildiAttribute == true)
                    {
                        continue;
                    }
                }
                else
                {
                    NotifyPropertyErisildiAttribute = item.GetCustomAttribute <NotifyPropertyErisildiAttribute>() != null;
                    if (NotifyPropertyErisildiAttribute == false)
                    {
                        continue;
                    }
                }

                PropertyBuilder PropertyYaratici = TipYaratici.DefineProperty(item.Name, PropertyAttributes.None, item.PropertyType, Type.EmptyTypes);
                MethodBuilder   getMethod        = TipYaratici.DefineMethod("get_" + item.Name, MethodAttributes.Public | MethodAttributes.Virtual, item.PropertyType, Type.EmptyTypes);
                ILGenerator     genericIL        = getMethod.GetILGenerator();
                genericIL.Emit(OpCodes.Ldarg_0);
                genericIL.Emit(OpCodes.Ldstr, item.Name);
                genericIL.Emit(OpCodes.Call, methodBuilder);
                genericIL.Emit(OpCodes.Ldarg_0);
                genericIL.Emit(OpCodes.Call, item.GetGetMethod());
                genericIL.Emit(OpCodes.Ret);
                PropertyYaratici.SetGetMethod(getMethod);

                MethodBuilder setMethod = TipYaratici.DefineMethod("set_" + item.Name, MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { item.PropertyType });
                genericIL = setMethod.GetILGenerator();
                genericIL.Emit(OpCodes.Ldarg_0);
                genericIL.Emit(OpCodes.Ldarg_1);
                genericIL.Emit(OpCodes.Call, item.GetSetMethod());
                genericIL.Emit(OpCodes.Ret);
                PropertyYaratici.SetSetMethod(setMethod);
            }

            return(Activator.CreateInstance(TipYaratici.CreateType()) as T);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Implements an interface event in a duck proxy type using a given type builder.
        /// If successful, the implemented event will be added to the given proxy member dictionary.
        /// </summary>
        /// <param name="proxyType">Type builder for the duck proxy type.</param>
        /// <param name="proxyMembers">Dictionary of members of the proxy type.</param>
        /// <param name="duckField">Field that holds a reference to the duck object to forward calls to.</param>
        /// <param name="constructorIL">IL generator to use to add code to the constructor if necessary.</param>
        /// <param name="interfaceEvent">The interface event to implement.</param>
        private void ImplementEvent(TypeBuilder proxyType, ProxyMemberDictionary proxyMembers, FieldInfo duckField, ILGenerator constructorIL, EventInfo interfaceEvent)
        {
            EventInfo duckEvent = FindDuckEvent(interfaceEvent);

            if (duckEvent == null)
            {
                throw new NotImplementedException("Duck type does not implement an event named \"" + interfaceEvent.Name + "\" with the same event handler type.");
            }

            EventBuilder proxyEvent = proxyType.DefineEvent(interfaceEvent.Name, EventAttributes.None, interfaceEvent.EventHandlerType);

            Type interfaceEventHandlerType = interfaceEvent.EventHandlerType;
            Type duckEventHandlerType      = duckEvent.EventHandlerType;

            // Define event add method
            MethodBuilder addMethod   = proxyType.DefineMethod("add_" + interfaceEvent.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, typeof(void), new Type[] { interfaceEventHandlerType });
            ILGenerator   addMethodIL = addMethod.GetILGenerator();

            // Define event remove method
            MethodBuilder removeMethod   = proxyType.DefineMethod("remove_" + interfaceEvent.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, typeof(void), new Type[] { interfaceEventHandlerType });
            ILGenerator   removeMethodIL = removeMethod.GetILGenerator();

            if (interfaceEventHandlerType == duckEventHandlerType)
            {
                // If the event handler types are the same, we can just forward calls to add and remove like normal.

                MethodInfo duckAddMethod = duckEvent.GetAddMethod();
                if (!duckAddMethod.IsStatic)
                {
                    addMethodIL.Emit(OpCodes.Ldarg_0);
                    addMethodIL.Emit(OpCodes.Ldfld, duckField);
                    addMethodIL.Emit(OpCodes.Ldarg_1);
                    addMethodIL.Emit(OpCodes.Callvirt, duckAddMethod);
                }
                else
                {
                    addMethodIL.Emit(OpCodes.Ldarg_1);
                    addMethodIL.Emit(OpCodes.Call, duckAddMethod);
                }

                MethodInfo duckRemoveMethod = duckEvent.GetRemoveMethod();
                if (!duckRemoveMethod.IsStatic)
                {
                    removeMethodIL.Emit(OpCodes.Ldarg_0);
                    removeMethodIL.Emit(OpCodes.Ldfld, duckField);
                    removeMethodIL.Emit(OpCodes.Ldarg_1);
                    removeMethodIL.Emit(OpCodes.Callvirt, duckRemoveMethod);
                }
                else
                {
                    removeMethodIL.Emit(OpCodes.Ldarg_1);
                    removeMethodIL.Emit(OpCodes.Call, duckRemoveMethod);
                }
            }
            else
            {
                // If the event handler types are different, we need some special behavior.  Specifically, the event handlers
                // added using the interface are kept as a seperate multicast delegate in the proxy class and an event handler
                // is added to the duck that calls the proxy event delegate.

                // Define the event multicast delegate field
                FieldBuilder eventHandlerField = proxyType.DefineField(interfaceEvent.Name, interfaceEventHandlerType, FieldAttributes.Private);

                // Implement the add method
                addMethodIL.Emit(OpCodes.Ldarg_0);
                addMethodIL.Emit(OpCodes.Ldarg_0);
                addMethodIL.Emit(OpCodes.Ldfld, eventHandlerField);
                addMethodIL.Emit(OpCodes.Ldarg_1);
                addMethodIL.Emit(OpCodes.Call, typeof(Delegate).GetMethod("Combine", new Type[] { typeof(Delegate), typeof(Delegate) }));
                addMethodIL.Emit(OpCodes.Castclass, interfaceEventHandlerType);
                addMethodIL.Emit(OpCodes.Stfld, eventHandlerField);

                // Implement the remove method
                removeMethodIL.Emit(OpCodes.Ldarg_0);
                removeMethodIL.Emit(OpCodes.Ldarg_0);
                removeMethodIL.Emit(OpCodes.Ldfld, eventHandlerField);
                removeMethodIL.Emit(OpCodes.Ldarg_1);
                removeMethodIL.Emit(OpCodes.Call, typeof(Delegate).GetMethod("Remove", new Type[] { typeof(Delegate), typeof(Delegate) }));
                removeMethodIL.Emit(OpCodes.Castclass, interfaceEventHandlerType);
                removeMethodIL.Emit(OpCodes.Stfld, eventHandlerField);

                // Set some local variables for later use...
                MethodInfo interfaceInvokeMethod = interfaceEventHandlerType.GetMethod("Invoke");
                Type[]     interfaceInvokeMethodParameterTypes = GetParameterTypes(interfaceInvokeMethod.GetParameters());

                MethodInfo duckInvokeMethod = duckEventHandlerType.GetMethod("Invoke");
                Type[]     duckInvokeMethodParameterTypes = GetParameterTypes(duckInvokeMethod.GetParameters());


                // Define the method that will serve as an event handler to the duck which will invoke the proxy's delegate
                MethodBuilder proxyInvokeMethod   = proxyType.DefineMethod("Invoke" + interfaceEvent.Name, MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final, CallingConventions.HasThis, duckInvokeMethod.ReturnType, duckInvokeMethodParameterTypes);
                ILGenerator   proxyInvokeMethodIL = proxyInvokeMethod.GetILGenerator();

                // First, check if the proxy event handler is null
                Label ifEventHandlerIsNullLabel = proxyInvokeMethodIL.DefineLabel();
                proxyInvokeMethodIL.Emit(OpCodes.Ldarg_0);
                proxyInvokeMethodIL.Emit(OpCodes.Ldfld, eventHandlerField);
                proxyInvokeMethodIL.Emit(OpCodes.Ldnull);
                proxyInvokeMethodIL.Emit(OpCodes.Ceq);
                proxyInvokeMethodIL.Emit(OpCodes.Brtrue_S, ifEventHandlerIsNullLabel);

                // If the proxy event handler is not null, invoke it
                proxyInvokeMethodIL.Emit(OpCodes.Ldarg_0);
                proxyInvokeMethodIL.Emit(OpCodes.Ldfld, eventHandlerField);
                for (int i = 0; i < interfaceInvokeMethodParameterTypes.Length; i++)
                {
                    proxyInvokeMethodIL.Emit(OpCodes.Ldarg, i + 1);
                    DuckTyping.EmitCastIL(proxyInvokeMethodIL, interfaceInvokeMethodParameterTypes[i], duckInvokeMethodParameterTypes[i]);
                }
                proxyInvokeMethodIL.Emit(OpCodes.Callvirt, interfaceInvokeMethod);

                // If the proxy event handler is null, execution jumps here
                proxyInvokeMethodIL.MarkLabel(ifEventHandlerIsNullLabel);

                // Return
                proxyInvokeMethodIL.Emit(OpCodes.Ret);


                // Add code to the constructor to add the event handler to the duck.
                MethodInfo duckAddMethod = duckEvent.GetAddMethod();
                if (!duckAddMethod.IsStatic)
                {
                    constructorIL.Emit(OpCodes.Ldarg_0);
                    constructorIL.Emit(OpCodes.Ldfld, duckField);
                }
                constructorIL.Emit(OpCodes.Ldarg_0);
                constructorIL.Emit(OpCodes.Ldftn, proxyInvokeMethod);
                constructorIL.Emit(OpCodes.Newobj, duckEventHandlerType.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }));
                if (!duckAddMethod.IsStatic)
                {
                    constructorIL.Emit(OpCodes.Callvirt, duckAddMethod);
                }
                else
                {
                    constructorIL.Emit(OpCodes.Call, duckAddMethod);
                }
            }

            // Finish add method and set it for the event
            addMethodIL.Emit(OpCodes.Ret);
            proxyEvent.SetAddOnMethod(addMethod);

            // Finish remove method and set it for the event
            removeMethodIL.Emit(OpCodes.Ret);
            proxyEvent.SetRemoveOnMethod(removeMethod);

            // Other associated methods appear before the event in the member array; thus, they have already been
            // defined and implemented.  The proxy member dictionary is used to refer to these.
            MethodInfo raiseMethod = duckEvent.GetRaiseMethod();

            if (raiseMethod != null)
            {
                proxyEvent.SetRaiseMethod((MethodBuilder)(proxyMembers[raiseMethod]));
            }

            MethodInfo[] otherDuckMethods = duckEvent.GetOtherMethods();
            foreach (MethodInfo otherDuckMethod in otherDuckMethods)
            {
                if (proxyMembers.ContainsKey(otherDuckMethod))
                {
                    proxyEvent.AddOtherMethod((MethodBuilder)(proxyMembers[otherDuckMethod]));
                }
            }

            // Add proxy event to the proxy member dictionary
            // (This is not really necessary, but good to keep things consistent)
            // if (proxyMembers != null) proxyMembers[duckEvent] =  proxyEvent;
            // For some reason, EventBuilder does not inherit MemberInfo, so it cannot be added.
        }
Exemplo n.º 20
0
        internal override void Implement(TypeBuilder typeBuilder)
        {
            MethodInfo delegateCombine = typeof(Delegate).GetMethod("Combine", new Type[] { typeof(Delegate), typeof(Delegate) });
            MethodInfo delegateRemove  = typeof(Delegate).GetMethod("Remove", new Type[] { typeof(Delegate), typeof(Delegate) });

            MethodInfo invokeDelegate = typeof(PropertyChangedEventHandler).GetMethod("Invoke");

            FieldBuilder eventBack = typeBuilder.DefineField("PropertyChanged", typeof(PropertyChangedEventHandler), FieldAttributes.Private);

            ConstructorInfo createEventArgs = typeof(PropertyChangedEventArgs).GetConstructor(new Type[] { typeof(String) });

            MethodBuilder addPropertyChanged = typeBuilder.DefineMethod("add_PropertyChanged",
                                                                        MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                                                                        typeof(void),
                                                                        new Type[] { typeof(PropertyChangedEventHandler) });

            ILGenerator gen = addPropertyChanged.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Call, delegateCombine);
            gen.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Stfld, eventBack);
            gen.Emit(OpCodes.Ret);

            MethodBuilder removePropertyChanged = typeBuilder.DefineMethod("remove_PropertyChanged",
                                                                           MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                                                                           typeof(void),
                                                                           new Type[] { typeof(PropertyChangedEventHandler) });

            gen = removePropertyChanged.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Call, delegateRemove);
            gen.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Stfld, eventBack);
            gen.Emit(OpCodes.Ret);

            MethodBuilder raisePropertyChanged = typeBuilder.DefineMethod("OnPropertyChanged",
                                                                          MethodAttributes.Public,
                                                                          typeof(void),
                                                                          new Type[] { typeof(String) });

            _raisePropertyChanged = raisePropertyChanged;

            gen = raisePropertyChanged.GetILGenerator();

            Label lblDelegateOk = gen.DefineLabel();

            gen.DeclareLocal(typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldnull);
            gen.Emit(OpCodes.Ceq);
            gen.Emit(OpCodes.Brtrue, lblDelegateOk);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Newobj, createEventArgs);
            gen.Emit(OpCodes.Callvirt, invokeDelegate);
            gen.MarkLabel(lblDelegateOk);
            gen.Emit(OpCodes.Ret);

            EventBuilder eventBuilder = typeBuilder.DefineEvent("PropertyChanged", EventAttributes.None, typeof(PropertyChangedEventHandler));

            eventBuilder.SetRaiseMethod(raisePropertyChanged);
            eventBuilder.SetAddOnMethod(addPropertyChanged);
            eventBuilder.SetRemoveOnMethod(removePropertyChanged);
        }
            internal void AddInterfaceImpl(Type iface)
            {
                // If necessary, generate an attribute to permit visibility
                // to internal types.
                _assembly.EnsureTypeIsVisible(iface);

                _tb.AddInterfaceImplementation(iface);

                // AccessorMethods -> Metadata mappings.
                var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod);
                    if (pi.GetMethod != null)
                    {
                        propertyMap[pi.GetMethod] = ai;
                    }
                    if (pi.SetMethod != null)
                    {
                        propertyMap[pi.SetMethod] = ai;
                    }
                }

                var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                    if (ei.AddMethod != null)
                    {
                        eventMap[ei.AddMethod] = ai;
                    }
                    if (ei.RemoveMethod != null)
                    {
                        eventMap[ei.RemoveMethod] = ai;
                    }
                    if (ei.RaiseMethod != null)
                    {
                        eventMap[ei.RaiseMethod] = ai;
                    }
                }

                foreach (MethodInfo mi in iface.GetRuntimeMethods())
                {
                    // Skip regular/non-virtual instance methods, static methods, and methods that cannot be overriden
                    // ("methods that cannot be overriden" includes default implementation of other interface methods).
                    if (!mi.IsVirtual || mi.IsFinal)
                    {
                        continue;
                    }

                    MethodBuilder        mdb = AddMethodImpl(mi);
                    PropertyAccessorInfo associatedProperty;
                    if (propertyMap.TryGetValue(mi, out associatedProperty))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                        {
                            associatedProperty.GetMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedProperty.SetMethodBuilder = mdb;
                        }
                    }

                    EventAccessorInfo associatedEvent;
                    if (eventMap.TryGetValue(mi, out associatedEvent))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                        {
                            associatedEvent.AddMethodBuilder = mdb;
                        }
                        else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                        {
                            associatedEvent.RemoveMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedEvent.RaiseMethodBuilder = mdb;
                        }
                    }
                }

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod];

                    // If we didn't make an overriden accessor above, this was a static property, non-virtual property,
                    // or a default implementation of a property of a different interface. In any case, we don't need
                    // to redeclare it.
                    if (ai.GetMethodBuilder == null && ai.SetMethodBuilder == null)
                    {
                        continue;
                    }

                    PropertyBuilder pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray());
                    if (ai.GetMethodBuilder != null)
                    {
                        pb.SetGetMethod(ai.GetMethodBuilder);
                    }
                    if (ai.SetMethodBuilder != null)
                    {
                        pb.SetSetMethod(ai.SetMethodBuilder);
                    }
                }

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    EventAccessorInfo ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];

                    // If we didn't make an overriden accessor above, this was a static event, non-virtual event,
                    // or a default implementation of an event of a different interface. In any case, we don't
                    // need to redeclare it.
                    if (ai.AddMethodBuilder == null && ai.RemoveMethodBuilder == null && ai.RaiseMethodBuilder == null)
                    {
                        continue;
                    }

                    EventBuilder eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType);
                    if (ai.AddMethodBuilder != null)
                    {
                        eb.SetAddOnMethod(ai.AddMethodBuilder);
                    }
                    if (ai.RemoveMethodBuilder != null)
                    {
                        eb.SetRemoveOnMethod(ai.RemoveMethodBuilder);
                    }
                    if (ai.RaiseMethodBuilder != null)
                    {
                        eb.SetRaiseMethod(ai.RaiseMethodBuilder);
                    }
                }
            }
Exemplo n.º 22
0
            internal void AddInterfaceImpl(Type iface)
            {
                // If necessary, generate an attribute to permit visibility
                // to internal types.
                _assembly.EnsureTypeIsVisible(iface);

                _tb.AddInterfaceImplementation(iface);

                // AccessorMethods -> Metadata mappings.
                var propertyMap = new Dictionary <MethodInfo, PropertyAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    var ai = new PropertyAccessorInfo(pi.GetMethod, pi.SetMethod);
                    if (pi.GetMethod != null)
                    {
                        propertyMap[pi.GetMethod] = ai;
                    }
                    if (pi.SetMethod != null)
                    {
                        propertyMap[pi.SetMethod] = ai;
                    }
                }

                var eventMap = new Dictionary <MethodInfo, EventAccessorInfo>(MethodInfoEqualityComparer.Instance);

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    var ai = new EventAccessorInfo(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                    if (ei.AddMethod != null)
                    {
                        eventMap[ei.AddMethod] = ai;
                    }
                    if (ei.RemoveMethod != null)
                    {
                        eventMap[ei.RemoveMethod] = ai;
                    }
                    if (ei.RaiseMethod != null)
                    {
                        eventMap[ei.RaiseMethod] = ai;
                    }
                }

                foreach (MethodInfo mi in iface.GetRuntimeMethods())
                {
                    MethodBuilder        mdb = AddMethodImpl(mi);
                    PropertyAccessorInfo associatedProperty;
                    if (propertyMap.TryGetValue(mi, out associatedProperty))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                        {
                            associatedProperty.GetMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedProperty.SetMethodBuilder = mdb;
                        }
                    }

                    EventAccessorInfo associatedEvent;
                    if (eventMap.TryGetValue(mi, out associatedEvent))
                    {
                        if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                        {
                            associatedEvent.AddMethodBuilder = mdb;
                        }
                        else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                        {
                            associatedEvent.RemoveMethodBuilder = mdb;
                        }
                        else
                        {
                            associatedEvent.RaiseMethodBuilder = mdb;
                        }
                    }
                }

                foreach (PropertyInfo pi in iface.GetRuntimeProperties())
                {
                    PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod];
                    PropertyBuilder      pb = _tb.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, pi.GetIndexParameters().Select(p => p.ParameterType).ToArray());
                    if (ai.GetMethodBuilder != null)
                    {
                        pb.SetGetMethod(ai.GetMethodBuilder);
                    }
                    if (ai.SetMethodBuilder != null)
                    {
                        pb.SetSetMethod(ai.SetMethodBuilder);
                    }
                }

                foreach (EventInfo ei in iface.GetRuntimeEvents())
                {
                    EventAccessorInfo ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];
                    EventBuilder      eb = _tb.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType);
                    if (ai.AddMethodBuilder != null)
                    {
                        eb.SetAddOnMethod(ai.AddMethodBuilder);
                    }
                    if (ai.RemoveMethodBuilder != null)
                    {
                        eb.SetRemoveOnMethod(ai.RemoveMethodBuilder);
                    }
                    if (ai.RaiseMethodBuilder != null)
                    {
                        eb.SetRaiseMethod(ai.RaiseMethodBuilder);
                    }
                }
            }
        private MethodBuilder GenerateILForINotifyPropertyChanged()
        {
            MethodInfo DelegateCombine = typeof(Delegate).GetMethod("Combine", new Type[] {
                typeof(Delegate), typeof(Delegate)
            });
            MethodInfo DelegateRemove = typeof(Delegate).GetMethod("Remove", new Type[] {
                typeof(Delegate), typeof(Delegate)
            });
            MethodInfo      InvokeDelegate  = typeof(PropertyChangedEventHandler).GetMethod("Invoke");
            FieldBuilder    eventBack       = typeBuilder.DefineField("PropertyChanged", typeof(PropertyChangingEventHandler), FieldAttributes.Private);
            ConstructorInfo CreateEventArgs = typeof(PropertyChangingEventArgs).GetConstructor(new Type[] {
                typeof(String)
            });


            MethodBuilder AddPropertyChanged = typeBuilder.DefineMethod(
                "add_PropertyChanged", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                typeof(void), new Type[] {
                typeof(PropertyChangedEventHandler)
            });
            ILGenerator gen = AddPropertyChanged.GetILGenerator();

            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Call, DelegateCombine);
            gen.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Stfld, eventBack);
            gen.Emit(OpCodes.Ret);

            MethodBuilder RemovePropertyChanged = typeBuilder.DefineMethod(
                "remove_PropertyChanged", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot,
                typeof(void), new Type[] {
                typeof(PropertyChangedEventHandler)
            });

            gen = RemovePropertyChanged.GetILGenerator();
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Call, DelegateRemove);
            gen.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Stfld, eventBack);
            gen.Emit(OpCodes.Ret);

            MethodBuilder RaisePropertyChanged = typeBuilder.DefineMethod(
                "OnPropertyChanged", MethodAttributes.Public,
                typeof(void), new Type[] {
                typeof(String)
            });

            gen = RaisePropertyChanged.GetILGenerator();
            Label lblDelegateOk = gen.DefineLabel();

            gen.DeclareLocal(typeof(PropertyChangedEventHandler));
            gen.Emit(OpCodes.Nop);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, eventBack);
            gen.Emit(OpCodes.Stloc_0);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldnull);
            gen.Emit(OpCodes.Ceq);
            gen.Emit(OpCodes.Brtrue, lblDelegateOk);
            gen.Emit(OpCodes.Ldloc_0);
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldarg_1);
            gen.Emit(OpCodes.Newobj, CreateEventArgs);
            gen.Emit(OpCodes.Callvirt, InvokeDelegate);
            gen.MarkLabel(lblDelegateOk);
            gen.Emit(OpCodes.Ret);

            EventBuilder pcevent = typeBuilder.DefineEvent("PropertyChanged", EventAttributes.None, typeof(PropertyChangedEventHandler));

            pcevent.SetRaiseMethod(RaisePropertyChanged);
            pcevent.SetAddOnMethod(AddPropertyChanged);
            pcevent.SetRemoveOnMethod(RemovePropertyChanged);

            return(RaisePropertyChanged);
        }
Exemplo n.º 24
0
 public void TestSetRaiseMethod1()
 {
     eb.SetRaiseMethod(null);
 }
Exemplo n.º 25
0
        public void SetRaiseMethod(IMethodBuilder raiseMethodBuilder)
        {
            var adapter = ArgumentUtility.CheckNotNullAndType <MethodBuilderAdapter> ("raiseMethodBuilder", raiseMethodBuilder);

            _eventBuilder.SetRaiseMethod(adapter.AdaptedMethodBuilder);
        }
Exemplo n.º 26
0
        public void TestThrowsExceptionOnNullBuilder()
        {
            EventBuilder ev = TypeBuilder.DefineEvent("Event_NegTest1", EventAttributes.None, typeof(TestEventHandler));

            Assert.Throws <ArgumentNullException>(() => { ev.SetRaiseMethod(null); });
        }