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); }
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); }
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); }
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); }); }
/// <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)); }
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); }
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)); }
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])); }
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; } }
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()); } }
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); }
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); }
/// <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. }
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); } } }
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); }
public void TestSetRaiseMethod1() { eb.SetRaiseMethod(null); }
public void SetRaiseMethod(IMethodBuilder raiseMethodBuilder) { var adapter = ArgumentUtility.CheckNotNullAndType <MethodBuilderAdapter> ("raiseMethodBuilder", raiseMethodBuilder); _eventBuilder.SetRaiseMethod(adapter.AdaptedMethodBuilder); }
public void TestThrowsExceptionOnNullBuilder() { EventBuilder ev = TypeBuilder.DefineEvent("Event_NegTest1", EventAttributes.None, typeof(TestEventHandler)); Assert.Throws <ArgumentNullException>(() => { ev.SetRaiseMethod(null); }); }