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