public void RaiseCanExecuteChangedFor(ProxyScope proxyScope, ILGenerator il, string propertyName) { if (il is null) { throw new ArgumentNullException(nameof(il)); } if (propertyName is null) { throw new ArgumentNullException(nameof(propertyName)); } var commands = ViewModelSupport.GetCommandInfos(proxyScope.TypeDefinition.Type).Where(p => p.CanExecutePropertyNames.Contains(propertyName)); if (commands.Count() == 0) { return; } foreach (var command in commands) { // find the method builder created for the proxy var getMethod = proxyScope.Methods.FirstOrDefault(p => p.Name == $"get_{command.CommandName}"); if (getMethod == null) { throw new ArgumentException($"No method found for the command '{command.CommandName}'"); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, getMethod); il.Emit(OpCodes.Callvirt, RaiseCanExecuteChangedMethod); } }
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 Set_Fields_Correctly() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(TypeScope1), 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(9, proxyScope.Fields.Count); Assert.AreEqual("__interceptors", proxyScope.Fields[0].Name); Assert.AreEqual("TypeScope1_MyProperty", proxyScope.Fields[1].Name); Assert.AreEqual("TypeScope1_Proxy_get_MyProperty", proxyScope.Fields[2].Name); Assert.AreEqual("TypeScope1_Proxy_set_MyProperty", proxyScope.Fields[3].Name); Assert.AreEqual("TypeScope1_Method", proxyScope.Fields[4].Name); Assert.AreEqual("TypeScope1_Proxy_Method", proxyScope.Fields[5].Name); Assert.AreEqual("TypeScope1_MyEvent", proxyScope.Fields[6].Name); Assert.AreEqual("TypeScope1_Proxy_add_MyEvent", proxyScope.Fields[7].Name); Assert.AreEqual("TypeScope1_Proxy_remove_MyEvent", proxyScope.Fields[8].Name); }
public bool CheckEquals(ProxyScope proxyScope, ILGenerator il, MethodInfo method) { if (!IsSetMethod(method.Name)) { return(false); } string propertyName = GetPropertyName(method.Name); var equalLocalBuilder = il.DeclareLocal(typeof(bool)); var equalLabel = il.DefineLabel(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, method.DeclaringType.GetMethod($"get_{propertyName}")); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Stloc, equalLocalBuilder); il.Emit(OpCodes.Ldloc, equalLocalBuilder); il.Emit(OpCodes.Brfalse_S, equalLabel); il.Emit(OpCodes.Ret); il.MarkLabel(equalLabel); return(true); }
public void Set_Properties_Methods_Events_Correctly() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(TypeScope1), null, null); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); proxyScope.DefineTypeAndMembers(); Assert.AreEqual(1, proxyScope.Properties.Count); Assert.AreEqual("MyProperty", proxyScope.Properties[0].Name); Assert.AreEqual(10, proxyScope.Methods.Count); // get set meth, add, remove Assert.AreEqual("get_MyProperty_Callback", proxyScope.Methods[0].Name); Assert.AreEqual("get_MyProperty", proxyScope.Methods[1].Name); Assert.AreEqual("set_MyProperty_Callback", proxyScope.Methods[2].Name); Assert.AreEqual("set_MyProperty", proxyScope.Methods[3].Name); Assert.AreEqual("Method_Callback", proxyScope.Methods[4].Name); Assert.AreEqual("Method", proxyScope.Methods[5].Name); Assert.AreEqual("add_MyEvent_Callback", proxyScope.Methods[6].Name); Assert.AreEqual("add_MyEvent", proxyScope.Methods[7].Name); Assert.AreEqual("remove_MyEvent_Callback", proxyScope.Methods[8].Name); Assert.AreEqual("remove_MyEvent", proxyScope.Methods[9].Name); Assert.AreEqual(1, proxyScope.Events.Count); Assert.AreEqual("MyEvent", proxyScope.Events[0].GetName()); }
public void CreateCommands(ProxyScope proxyScope, IEnumerable <CommandInfo> commands) { foreach (var command in commands) { CreateDelegateCommand(proxyScope, command.CommandName, command.ExecuteMethod, command.CanExecuteMethod); } }
public void AddINotifyPropertyChangedInterface(ProxyScope proxyScope) { if (!proxyScope.HasImplementedInterface(interfaceType)) { proxyScope.AddInterfaceImplementation(interfaceType); } }
public override void BeforeInvoke(ProxyScope proxyScope, ILGenerator il, CallbackMethodDefinition callbackMethodDefinition) { // never called with clean get and set method builder if (callbackMethodDefinition.MethodDefinition.MethodDefinitionType == MethodDefinitionType.Setter && ViewModelSupport.IsViewModel(proxyScope.TypeDefinition.Type)) { notifyPropertyChangedFeature.CheckEquals(proxyScope, il, callbackMethodDefinition.Method); } }
protected Type GetOrCreateInvocationType(ProxyScope proxyScope, MethodDefinition methodDefinition, MethodBuilder callbackMethodBuilder) { Type invocationType = proxyScope.ModuleScope.GetOrCreateInvocationType(methodDefinition.InvocationTypeDefinition, callbackMethodBuilder); if (invocationType.IsGenericType) { invocationType = invocationType.MakeGenericType(methodDefinition.Method.GetGenericArguments()); } return(invocationType); }
public override void BeforeDefine(ProxyScope proxyScope) { if (ViewModelSupport.IsViewModel(proxyScope.TypeDefinition.Type)) { notifyPropertyChangedFeature.ImplementFeature(proxyScope); var commands = ViewModelSupport.GetCommandInfos(proxyScope.TypeDefinition.Type); delegateCommandBuilder.CreateCommands(proxyScope, commands); } }
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 ImplementFeature(ProxyScope proxyScope) { // interface AddINotifyPropertyChangedInterface(proxyScope); // event CreatePropertyChangedEventHandler(proxyScope); // Method CreateOnPropertyChangedMethod(proxyScope); }
public override void AfterInvoke(ProxyScope proxyScope, ILGenerator il, CallbackMethodDefinition callbackMethodDefinition) { // never called with clean get and set method builder if (callbackMethodDefinition.MethodDefinition.MethodDefinitionType == MethodDefinitionType.Setter && ViewModelSupport.IsViewModel(proxyScope.TypeDefinition.Type)) { notifyPropertyChangedFeature.InvokeOnPropertyChanged(proxyScope, il, callbackMethodDefinition.Method); string propertyName = (callbackMethodDefinition.MethodDefinition as SetMethodDefinition).PropertyDefinition.Name; delegateCommandBuilder.RaiseCanExecuteChangedFor(proxyScope, il, propertyName); } }
private MethodBuilder DefineMethodAndParameters(ProxyScope proxyScope, MethodDefinition methodDefinition) { 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); } return(methodBuilder); }
public void CreateOnPropertyChangedMethod(ProxyScope proxyScope) { FieldBuilder eventField = proxyScope.Fields.FirstOrDefault(p => p.Name == EventName); if (eventField == null) { throw new ArgumentException($"No field '{EventName}' found."); } var onPropertyChangedMethodBuilder = GetOnPropertyChangedMethod(proxyScope); if (onPropertyChangedMethodBuilder == null) { onPropertyChangedMethodBuilder = proxyScope.DefineMethod(MethodName, MethodAttributes.Family, typeof(void), new Type[] { typeof(string) }); onPropertyChangedMethodBuilder.DefineParameter(1, ParameterAttributes.None, ParameterName); var il = onPropertyChangedMethodBuilder.GetILGenerator(); var isNullLocal = il.DeclareLocal(typeof(bool)); var label = il.DefineLabel(); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, eventField); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Cgt_Un); il.Emit(OpCodes.Stloc, isNullLocal); il.Emit(OpCodes.Ldloc, isNullLocal); il.Emit(OpCodes.Brfalse_S, label); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, eventField); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Newobj, PropertyChangedEventArgsConstructor); il.Emit(OpCodes.Callvirt, InvokeMethod); il.MarkLabel(label); il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret); } }
public void CreateInterceptableEvent_Adds_Fields_Event_Methods_And_Mapping() { var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(TypeScope1), null, null); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); // proxyScope.DefineTypeAndMembers(); proxyScope.GetType().GetMethod("CreateFields", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(proxyScope, new object[0]); Assert.AreEqual(1, proxyScope.Fields.Count); Assert.AreEqual(0, proxyScope.Properties.Count); Assert.AreEqual(0, proxyScope.Methods.Count); var er = proxyScope.CreateInterceptableEvent(typeDefinition.EventDefinitions[0]); Assert.AreEqual(4, proxyScope.Fields.Count); Assert.AreEqual("TypeScope1_MyEvent", proxyScope.Fields[1].Name); Assert.AreEqual("TypeScope1_Proxy_add_MyEvent", proxyScope.Fields[2].Name); Assert.AreEqual("TypeScope1_Proxy_remove_MyEvent", proxyScope.Fields[3].Name); Assert.AreEqual(4, proxyScope.Methods.Count); Assert.AreEqual("add_MyEvent_Callback", proxyScope.Methods[0].Name); Assert.AreEqual("add_MyEvent", proxyScope.Methods[1].Name); Assert.AreEqual("remove_MyEvent_Callback", proxyScope.Methods[2].Name); Assert.AreEqual("remove_MyEvent", proxyScope.Methods[3].Name); var acc = new TypeAccessor(proxyScope); var mappings = acc.Fields["eventMappings"].GetValue() as List <EventMapping>; Assert.AreEqual(1, mappings.Count); Assert.AreEqual("TypeScope1_MyEvent", mappings[0].MemberField.Name); Assert.AreEqual("TypeScope1_Proxy_add_MyEvent", mappings[0].AddMethodField.Name); Assert.AreEqual("TypeScope1_Proxy_remove_MyEvent", mappings[0].RemoveMethodField.Name); Assert.AreEqual("MyEvent", mappings[0].Event.Name); Assert.AreEqual("add_MyEvent", mappings[0].AddMethodBuilder.Name); Assert.AreEqual("remove_MyEvent", mappings[0].RemoveMethodBuilder.Name); }
public void DefineEvent_Adds_EventBuilder() { 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); var m = proxyScope.DefineEvent("E", EventAttributes.None, typeof(EventHandler)); Assert.AreEqual(1, proxyScope.Events.Count); Assert.AreEqual("E", proxyScope.Events[0].GetName()); }
public override MethodBuilder CreateMethod(ProxyScope proxyScope, MethodDefinition methodDefinition, MemberInfo member, FieldBuilder memberField, FieldBuilder callerMethodField) { // create clean properties (invocation and callback method not added) if (ViewModelSupport.IsViewModel(proxyScope.TypeDefinition.Type)) { if (methodDefinition.MethodDefinitionType == MethodDefinitionType.Getter) { MethodBuilder methodBuilder = DefineMethodAndParameters(proxyScope, methodDefinition); var il = methodBuilder.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, methodDefinition.Method); il.Emit(OpCodes.Ret); return(methodBuilder); } if (methodDefinition.MethodDefinitionType == MethodDefinitionType.Setter) { // Setter raise OnPropertyChanged MethodBuilder methodBuilder = DefineMethodAndParameters(proxyScope, methodDefinition); var il = methodBuilder.GetILGenerator(); notifyPropertyChangedFeature.CheckEquals(proxyScope, il, methodDefinition.Method); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, methodDefinition.Method); notifyPropertyChangedFeature.InvokeOnPropertyChanged(proxyScope, il, methodDefinition.Method); string propertyName = (methodDefinition as SetMethodDefinition).PropertyDefinition.Name; delegateCommandBuilder.RaiseCanExecuteChangedFor(proxyScope, il, propertyName); il.Emit(OpCodes.Ret); return(methodBuilder); } } return(base.CreateMethod(proxyScope, methodDefinition, member, memberField, callerMethodField)); }
public void DefineProperty_Adds_PropertyBuilder() { 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); var property = proxyScope.DefineProperty("P", PropertyAttributes.None, typeof(string), new Type[] { typeof(string) }); Assert.AreEqual(1, proxyScope.Properties.Count); Assert.AreEqual("P", proxyScope.Properties[0].Name); Assert.AreEqual(property, proxyScope.Properties[0]); }
public bool InvokeOnPropertyChanged(ProxyScope proxyScope, ILGenerator il, MethodInfo method) { if (!IsSetMethod(method.Name)) { return(false); } string propertyName = GetPropertyName(method.Name); MethodBuilder onPropertyChangedMethodBuilder = GetOnPropertyChangedMethod(proxyScope); if (onPropertyChangedMethodBuilder == null) { throw new ArgumentNullException(nameof(onPropertyChangedMethodBuilder)); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldstr, propertyName); il.Emit(OpCodes.Call, onPropertyChangedMethodBuilder); return(true); }
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]); }
public void DefineMethod_Adds_MethodBuilder() { 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.Methods.Count); var m = proxyScope.DefineMethod("M", MethodAttributes.Public, typeof(string), new Type[] { typeof(string) }); Assert.AreEqual(1, proxyScope.Methods.Count); Assert.AreEqual("M", proxyScope.Methods[0].Name); var m2 = proxyScope.DefineMethod("M2", MethodAttributes.Public); Assert.AreEqual(2, proxyScope.Methods.Count); Assert.AreEqual("M2", proxyScope.Methods[1].Name); }
protected FieldBuilder FindConstructorField(ProxyScope proxyScope, string fieldName) { return(proxyScope.ConstructorFields.First(p => p.Name == fieldName)); }
protected MethodBuilder CreateCallbackMethod(ProxyScope proxyScope, CallbackMethodDefinition callbackMethodDefinition) { return(callbackMethodBuilder.CreateMethod(proxyScope, callbackMethodDefinition)); }
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); }
public MethodBuilder CreateMethod(ProxyScope proxyScope, CallbackMethodDefinition callbackMethodDefinition) { AdditionalCode additionalCode = (callbackMethodDefinition.TypeDefinition as ProxyTypeDefinition)?.Options?.AdditionalCode; // method MethodBuilder methodBuilder = proxyScope.DefineMethod(callbackMethodDefinition.Name, callbackMethodDefinition.MethodAttributes); methodBuilder.SetReturnType(callbackMethodDefinition.ReturnType); // parameters GenericTypeParameterBuilder[] genericTypeParameters = methodBuilder.DefineGenericParameters(callbackMethodDefinition.GenericArguments); if (callbackMethodDefinition.ParameterDefinitions.Length > 0) { DefineParameters(methodBuilder, callbackMethodDefinition); } // body var il = methodBuilder.GetILGenerator(); // locals LocalBuilder resultLocalBuilder = null; LocalBuilder targetLocalBuilder = null; Type returnType = callbackMethodDefinition.ReturnType; if (returnType != typeof(void)) { if (returnType.ContainsGenericParameters) { resultLocalBuilder = il.DeclareLocal(genericTypeParameters.First(p => p.Name == returnType.Name)); } else { resultLocalBuilder = il.DeclareLocal(returnType); } } Type targetType = callbackMethodDefinition.TypeDefinition.TargetType; if (targetType != null) { targetLocalBuilder = il.DeclareLocal(targetType); } il.Emit(OpCodes.Nop); // before if (additionalCode != null) { additionalCode.BeforeInvoke(proxyScope, il, callbackMethodDefinition); } if (targetType != null) { // return ((TargetType)target).Method(p1, p2 ...); string fieldName = callbackMethodDefinition.TypeDefinition.TargetFieldName; EmitHelper.StoreFieldToLocal(il, proxyScope.Fields.First(p => p.Name == fieldName), targetLocalBuilder); il.Emit(OpCodes.Ldloc, targetLocalBuilder); } else { // return base.Method(p1, p2...); il.Emit(OpCodes.Ldarg_0); } var parameterDefinitions = callbackMethodDefinition.ParameterDefinitions; for (int i = 0; i < parameterDefinitions.Length; i++) { il.EmitLdarg(i + 1); } if (callbackMethodDefinition.TypeDefinition.TypeDefinitionType == TypeDefinitionType.InterfaceProxy && targetType == null) { ThrowInterfaceProxyWithoutTargetException(il, callbackMethodDefinition); } else { CallMethodOnTarget(il, callbackMethodDefinition, genericTypeParameters); if (returnType != typeof(void)) { il.Emit(OpCodes.Stloc, resultLocalBuilder); } // after if (additionalCode != null) { additionalCode.AfterInvoke(proxyScope, il, callbackMethodDefinition); } if (returnType != typeof(void)) { il.Emit(OpCodes.Ldloc, resultLocalBuilder); } il.Emit(OpCodes.Nop); il.Emit(OpCodes.Ret); } return(methodBuilder); }
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 MethodBuilder GetOnPropertyChangedMethod(ProxyScope proxyScope) { return(proxyScope.Methods.FirstOrDefault(p => p.Name == MethodName)); }
public void Mixin_Do_Not_Include_Doublons_Test() { var o = new ProxyGeneratorOptions(); o.AddMixinInstance(new MyMixin()); var moduleScope = new ModuleScope(); var generator = new ProxyGenerator(moduleScope); var typeDefinition = generator.GetTypeDefinition(typeof(TypeScope1), null, o); TypeBuilder typeBulder = moduleScope.Module.DefineType(typeDefinition.FullName, typeDefinition.TypeAttributes); var proxyScope = new ProxyScope(moduleScope, typeBulder, typeDefinition); proxyScope.DefineTypeAndMembers(); Assert.AreEqual(1, proxyScope.Properties.Count); Assert.AreEqual("MyProperty", proxyScope.Properties[0].Name); Assert.AreEqual(10, proxyScope.Methods.Count); // get set meth, add, remove Assert.AreEqual("get_MyProperty_Callback", proxyScope.Methods[0].Name); Assert.AreEqual("get_MyProperty", proxyScope.Methods[1].Name); Assert.AreEqual("set_MyProperty_Callback", proxyScope.Methods[2].Name); Assert.AreEqual("set_MyProperty", proxyScope.Methods[3].Name); Assert.AreEqual("Method_Callback", proxyScope.Methods[4].Name); Assert.AreEqual("Method", proxyScope.Methods[5].Name); Assert.AreEqual("add_MyEvent_Callback", proxyScope.Methods[6].Name); Assert.AreEqual("add_MyEvent", proxyScope.Methods[7].Name); Assert.AreEqual("remove_MyEvent_Callback", proxyScope.Methods[8].Name); Assert.AreEqual("remove_MyEvent", proxyScope.Methods[9].Name); Assert.AreEqual(1, proxyScope.Events.Count); Assert.AreEqual("MyEvent", proxyScope.Events[0].GetName()); // fields Assert.AreEqual(2, proxyScope.ConstructorFields.Length); Assert.AreEqual("__interceptors", proxyScope.ConstructorFields[0].Name); Assert.AreEqual("__myMixin", proxyScope.ConstructorFields[1].Name); Assert.AreEqual(10, proxyScope.Fields.Count); Assert.AreEqual("__interceptors", proxyScope.Fields[0].Name); Assert.AreEqual("__myMixin", proxyScope.Fields[1].Name); Assert.AreEqual("TypeScope1_MyProperty", proxyScope.Fields[2].Name); Assert.AreEqual("TypeScope1_Proxy_get_MyProperty", proxyScope.Fields[3].Name); Assert.AreEqual("TypeScope1_Proxy_set_MyProperty", proxyScope.Fields[4].Name); Assert.AreEqual("TypeScope1_Method", proxyScope.Fields[5].Name); Assert.AreEqual("TypeScope1_Proxy_Method", proxyScope.Fields[6].Name); Assert.AreEqual("TypeScope1_MyEvent", proxyScope.Fields[7].Name); Assert.AreEqual("TypeScope1_Proxy_add_MyEvent", proxyScope.Fields[8].Name); Assert.AreEqual("TypeScope1_Proxy_remove_MyEvent", proxyScope.Fields[9].Name); // mappings var acc = new TypeAccessor(proxyScope); var propertyMappings = acc.Fields["propertyMappings"].GetValue() as List <PropertyMapping>; Assert.AreEqual(1, propertyMappings.Count); Assert.AreEqual("TypeScope1_MyProperty", propertyMappings[0].MemberField.Name); Assert.AreEqual("TypeScope1_Proxy_get_MyProperty", propertyMappings[0].GetMethodField.Name); Assert.AreEqual("TypeScope1_Proxy_set_MyProperty", propertyMappings[0].SetMethodField.Name); Assert.AreEqual("MyProperty", propertyMappings[0].Property.Name); Assert.AreEqual("get_MyProperty", propertyMappings[0].GetMethodBuilder.Name); Assert.AreEqual("set_MyProperty", propertyMappings[0].SetMethodBuilder.Name); var methodMappings = acc.Fields["methodMappings"].GetValue() as List <MethodMapping>; Assert.AreEqual(1, methodMappings.Count); Assert.AreEqual("TypeScope1_Method", methodMappings[0].MemberField.Name); Assert.AreEqual("TypeScope1_Proxy_Method", methodMappings[0].MethodField.Name); Assert.AreEqual("Method", methodMappings[0].Method.Name); Assert.AreEqual("Method", methodMappings[0].MethodBuilder.Name); var eventMappings = acc.Fields["eventMappings"].GetValue() as List <EventMapping>; Assert.AreEqual(1, eventMappings.Count); Assert.AreEqual("TypeScope1_MyEvent", eventMappings[0].MemberField.Name); Assert.AreEqual("TypeScope1_Proxy_add_MyEvent", eventMappings[0].AddMethodField.Name); Assert.AreEqual("TypeScope1_Proxy_remove_MyEvent", eventMappings[0].RemoveMethodField.Name); Assert.AreEqual("MyEvent", eventMappings[0].Event.Name); Assert.AreEqual("add_MyEvent", eventMappings[0].AddMethodBuilder.Name); Assert.AreEqual("remove_MyEvent", eventMappings[0].RemoveMethodBuilder.Name); }