public void DefineFullEvent_Adds_Methods_And_Event() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(EmpyType), null, null); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); proxyScope.DefineTypeAndMembers(); Assert.AreEqual(0, proxyScope.Events.Count); Assert.AreEqual(0, proxyScope.Methods.Count); FieldBuilder field = proxyScope.DefineField("_myEvent", typeof(EventHandler), FieldAttributes.Private); var m = proxyScope.DefineFullEvent("MyEvent", EventAttributes.None, typeof(EventHandler), field); Assert.AreEqual(1, proxyScope.Events.Count); Assert.AreEqual("MyEvent", proxyScope.Events[0].GetName()); Assert.AreEqual(2, proxyScope.Methods.Count); Assert.AreEqual("add_MyEvent", proxyScope.Methods[0].Name); Assert.AreEqual("remove_MyEvent", proxyScope.Methods[1].Name); }
public void DefineReadOnlyProperty_Adds_Methods_And_Property() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(EmpyType), null, null); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); proxyScope.DefineTypeAndMembers(); Assert.AreEqual(0, proxyScope.Properties.Count); Assert.AreEqual(0, proxyScope.Methods.Count); FieldBuilder field = proxyScope.DefineField("_myProperty", typeof(EventHandler), FieldAttributes.Private); var p = proxyScope.DefineReadOnlyProperty("MyProperty", PropertyAttributes.None, typeof(void), new Type[0], MethodAttributes.Public, field); Assert.AreEqual(1, proxyScope.Properties.Count); Assert.AreEqual("MyProperty", proxyScope.Properties[0].Name); Assert.AreEqual(1, proxyScope.Methods.Count); Assert.AreEqual("get_MyProperty", proxyScope.Methods[0].Name); }
public void CreatePropertyChangedEventHandler(ProxyScope proxyScope) { EventBuilder propertyChangedEventBuilder = proxyScope.Events.FirstOrDefault(p => p.GetName() == EventName); if (propertyChangedEventBuilder == null) { FieldBuilder eventField = proxyScope.DefineField(EventName, typeof(PropertyChangedEventHandler), FieldAttributes.Private); proxyScope.DefineFullEvent(EventName, EventAttributes.None, typeof(PropertyChangedEventHandler), eventField); } }
public void DefineField_Adds_FieldBuilder() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(EmpyType), null, null); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); proxyScope.DefineTypeAndMembers(); Assert.AreEqual(1, proxyScope.ConstructorFields.Length); Assert.AreEqual("__interceptors", proxyScope.ConstructorFields[0].Name); Assert.AreEqual(1, proxyScope.Fields.Count); Assert.AreEqual("__interceptors", proxyScope.Fields[0].Name); var field = proxyScope.DefineField("A", typeof(string), FieldAttributes.Private); Assert.AreEqual(1, proxyScope.ConstructorFields.Length); Assert.AreEqual(2, proxyScope.Fields.Count); Assert.AreEqual("A", proxyScope.Fields[1].Name); Assert.AreEqual(field, proxyScope.Fields[1]); }
protected virtual MethodBuilder CreateDelegateCommand(ProxyScope proxyScope, string commandName, MethodInfo executeMethod, MethodInfo canExecuteMethod) { if (commandName is null) { throw new ArgumentNullException(nameof(commandName)); } if (executeMethod is null) { throw new ArgumentNullException(nameof(executeMethod)); } Type parameterType = GetParameterType(executeMethod); Type delegateCommandType = null; ConstructorInfo actionCtor = null; if (parameterType == null) { delegateCommandType = typeof(DelegateCommand); actionCtor = ActionConstructor; } else { delegateCommandType = typeof(DelegateCommand <>).MakeGenericType(new Type[] { parameterType }); actionCtor = typeof(Action <>).MakeGenericType(new Type[] { parameterType }).GetConstructors()[0]; } PropertyBuilder propertyBuilder = proxyScope.DefineProperty(commandName, PropertyAttributes.None, delegateCommandType, new Type[0]); FieldBuilder field = proxyScope.DefineField($"_{NamingHelper.ToCamelCase(commandName)}", delegateCommandType, FieldAttributes.Private); // get method MethodBuilder methodBuilder = proxyScope.DefineMethod($"get_{commandName}", MethodAttributes.Public | MethodAttributes.HideBySig, delegateCommandType, new Type[0]); // body var il = methodBuilder.GetILGenerator(); var isNullLocal = il.DeclareLocal(typeof(bool)); var commandLocal = il.DeclareLocal(delegateCommandType); var isNullLabel = il.DefineLabel(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Stloc, isNullLocal); il.Emit(OpCodes.Ldloc, isNullLocal); il.Emit(OpCodes.Brfalse_S, isNullLabel); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldftn, executeMethod); il.Emit(OpCodes.Newobj, actionCtor); if (canExecuteMethod != null) { ConstructorInfo delegateCommandWithPredicateCtor = parameterType == null ? DelegateCommandWithPredicateConstructor : delegateCommandType.GetConstructors()[1]; ConstructorInfo funcCtor = parameterType == null ? FuncBoolConstructor : typeof(Func <,>).MakeGenericType(new Type[] { parameterType, typeof(bool) }).GetConstructors()[0]; il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldftn, canExecuteMethod); il.Emit(OpCodes.Newobj, funcCtor); il.Emit(OpCodes.Newobj, delegateCommandWithPredicateCtor); } else { ConstructorInfo delegateCommandCtor = parameterType == null ? DelegateCommandConstructor : delegateCommandType.GetConstructors()[0]; il.Emit(OpCodes.Newobj, delegateCommandCtor); } il.Emit(OpCodes.Stfld, field); il.MarkLabel(isNullLabel); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); il.Emit(OpCodes.Stloc, commandLocal); il.Emit(OpCodes.Ldloc, commandLocal); il.Emit(OpCodes.Ret); // set property method propertyBuilder.SetGetMethod(methodBuilder); return(methodBuilder); }
public virtual MethodBuilder CreateMethod(ProxyScope proxyScope, MethodDefinition methodDefinition, MemberInfo member, FieldBuilder memberField, FieldBuilder callerMethodField) { MethodInfo method = methodDefinition.Method; // callback method MethodBuilder callbackMethodBuilder = CreateCallbackMethod(proxyScope, methodDefinition.CallbackMethodDefinition); // invocation type Type invocationType = GetOrCreateInvocationType(proxyScope, methodDefinition, callbackMethodBuilder); // method MethodBuilder methodBuilder = proxyScope.DefineMethod(methodDefinition.Name, methodDefinition.MethodAttributes); methodBuilder.SetReturnType(methodDefinition.ReturnType); // parameters methodBuilder.DefineGenericParameters(methodDefinition.GenericArguments); if (methodDefinition.ParameterDefinitions.Length > 0) { DefineParameters(methodBuilder, methodDefinition); } // attributes DefineAttributes(methodBuilder, methodDefinition); // method body var il = methodBuilder.GetILGenerator(); // locals IInterceptorSelector interceptorSelector = proxyScope.TypeDefinition.Options?.InterceptorSelector; FieldBuilder interceptorSelectorField = null; FieldBuilder interceptorMethodField = null; if (interceptorSelector != null) { interceptorSelectorField = FindConstructorField(proxyScope, ProxyScope.InterceptorSelectorFieldName); interceptorMethodField = proxyScope.DefineField(methodDefinition.InterceptorSelectorFieldName, typeof(IInterceptor[]), FieldAttributes.Private); } var returnType = methodDefinition.ReturnType; Type targetType = methodDefinition.TypeDefinition.TargetType; Type localBuilderType = targetType != null ? targetType : typeof(object); LocalBuilder targetLocalBuilder = il.DeclareLocal(localBuilderType); // target LocalBuilder interceptorsLocalBuilder = il.DeclareLocal(typeof(IInterceptor[])); // interceptors LocalBuilder memberLocalBuilder = il.DeclareLocal(typeof(MemberInfo)); // MemberInfo LocalBuilder callerMethodLocalBuilder = il.DeclareLocal(typeof(MethodInfo)); // proxy method LocalBuilder proxyLocalBuilder = il.DeclareLocal(typeof(object)); // proxy LocalBuilder parametersLocalBuilder = il.DeclareLocal(typeof(object[])); // parameters LocalBuilder invocationLocalBuilder = il.DeclareLocal(invocationType); // invocation LocalBuilder returnValueLocalBuilder = null; if (returnType != typeof(void)) { returnValueLocalBuilder = il.DeclareLocal(returnType); } FieldBuilder interceptorsField = proxyScope.ConstructorFields[0]; if (targetType != null) { FieldBuilder targetField = FindConstructorField(proxyScope, methodDefinition.TypeDefinition.TargetFieldName); EmitHelper.StoreFieldToLocal(il, targetField, targetLocalBuilder); } EmitHelper.StoreFieldToLocal(il, memberField, memberLocalBuilder); EmitHelper.StoreFieldToLocal(il, callerMethodField, callerMethodLocalBuilder); EmitHelper.StoreThisToLocal(il, proxyLocalBuilder); if (interceptorSelector != null) { LocalBuilder isNullLocal = il.DeclareLocal(typeof(bool)); Label isNullLabel = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, interceptorMethodField); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Stloc, isNullLocal); il.Emit(OpCodes.Ldloc, isNullLocal); il.Emit(OpCodes.Brfalse_S, isNullLabel); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, interceptorSelectorField); il.Emit(OpCodes.Ldtoken, member.DeclaringType); il.Emit(OpCodes.Call, Methods.GetTypeFromHandle); il.Emit(OpCodes.Ldloc, callerMethodLocalBuilder); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, interceptorsField); il.Emit(OpCodes.Callvirt, Methods.SelectInterceptorsMethod); il.Emit(OpCodes.Stfld, interceptorMethodField); il.MarkLabel(isNullLabel); EmitHelper.StoreFieldToLocal(il, interceptorMethodField, interceptorsLocalBuilder); } else { EmitHelper.StoreFieldToLocal(il, interceptorsField, interceptorsLocalBuilder); } StoreArgsToArray(il, methodDefinition.ParameterDefinitions, parametersLocalBuilder); EmitHelper.CreateInvocation(il, invocationType, targetLocalBuilder, interceptorsLocalBuilder, memberLocalBuilder, callerMethodLocalBuilder, proxyLocalBuilder, parametersLocalBuilder, invocationLocalBuilder); EmitHelper.CallProceed(il, invocationLocalBuilder); // set ref parameters values after Proceed called SetByRefArgs(il, methodDefinition.ParameterDefinitions, invocationLocalBuilder); EmitReturnValue(il, method, invocationLocalBuilder, returnValueLocalBuilder); if (method.DeclaringType.IsInterface) { proxyScope.DefineMethodOverride(methodBuilder, method); } return(methodBuilder); }