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);
            }
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 6
0
        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);
     }
 }
Exemplo n.º 9
0
        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);
            }
        }
Exemplo n.º 10
0
        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);
        }
Exemplo n.º 11
0
        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);
        }
Exemplo n.º 14
0
        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);
            }
        }
Exemplo n.º 15
0
        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);
            }
        }
Exemplo n.º 17
0
        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);
        }
Exemplo n.º 18
0
        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());
        }
Exemplo n.º 19
0
        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));
        }
Exemplo n.º 20
0
        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);
        }
Exemplo n.º 22
0
        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]);
        }
Exemplo n.º 23
0
        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);
        }
Exemplo n.º 24
0
 protected FieldBuilder FindConstructorField(ProxyScope proxyScope, string fieldName)
 {
     return(proxyScope.ConstructorFields.First(p => p.Name == fieldName));
 }
Exemplo n.º 25
0
 protected MethodBuilder CreateCallbackMethod(ProxyScope proxyScope, CallbackMethodDefinition callbackMethodDefinition)
 {
     return(callbackMethodBuilder.CreateMethod(proxyScope, callbackMethodDefinition));
 }
Exemplo n.º 26
0
        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);
        }
Exemplo n.º 27
0
        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);
        }
Exemplo n.º 28
0
        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));
 }
Exemplo n.º 30
0
        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);
        }