示例#1
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);
        }
示例#2
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);
        }
        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);
            }
        }
示例#4
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]);
        }
        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);
        }
示例#6
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);
        }