Пример #1
0
        public void Test1()
        {
#if NET461
            var m = new ModuleEmitter(true);
#else
            var m = new ModuleEmitter();
#endif
            var classType = m.DefineType("test", TypeAttributes.Public);
            var method    = classType.DefineMethod("Test", MethodAttributes.Public, typeof(int));

            var pI = method.DefineParameter(typeof(int), ParameterAttributes.None, "i");
            var pJ = method.DefineParameter(typeof(int), ParameterAttributes.None, "j");

            var b = Variable(typeof(Expression));

            method.Append(Assign(b, Constant(GetExpression(entry => entry.Id))));

            var switchAst = Switch(Constant(1));

            switchAst.Case(Constant(1))
            .Append(IncrementAssign(pI));

            switchAst.Case(Constant(2))
            .Append(AddAssign(pI, Constant(5)));

            var constantAst2 = Constant(1, typeof(object));

            var switchAst2 = Switch(constantAst2);

            var stringAst = Variable(typeof(string));
            var intAst    = Variable(typeof(int));

            switchAst2.Case(stringAst);
            switchAst2.Case(intAst)
            .Append(Assign(pI, intAst));

            var switchAst3 = Switch(Constant("ABC"), DecrementAssign(pI), typeof(void));

            switchAst3.Case(Constant("A"))
            .Append(IncrementAssign(pI));

            switchAst3.Case(Constant("B"))
            .Append(AddAssign(pI, Constant(5)));

            method.Append(switchAst)
            .Append(switchAst2)
            .Append(switchAst3)
            .Append(Return(Condition(GreaterThanOrEqual(pI, pJ), pI, pJ)));

            var type = classType.CreateType();
#if NET461
            m.SaveAssembly();
#endif
        }
Пример #2
0
        private ServiceDescriptor ResolveIsInterface()
        {
            string name = string.Concat(serviceType.Name, "Proxy");

            var interfaces = serviceType.GetAllInterfaces();

            var classEmitter = moduleEmitter.DefineType(name, TypeAttributes.Public | TypeAttributes.Class, null, interfaces);

            var instanceAst = classEmitter.DefineField("____instance__", serviceType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.NotSerialized);

            var constructorEmitter = classEmitter.DefineConstructor(MethodAttributes.Public);

            var parameterEmitter = constructorEmitter.DefineParameter(serviceType, ParameterAttributes.None, "instance");

            constructorEmitter.Append(Assign(instanceAst, parameterEmitter));

            var interceptMethods = new Dictionary <MethodInfo, IList <CustomAttributeData> >(MethodInfoEqualityComparer.Instance);

            foreach (var type in interfaces)
            {
                bool flag = type.IsDefined(InterceptAttributeType, false);

                var attributes = flag
                    ? type.GetCustomAttributesData()
                    : new CustomAttributeData[0];

                foreach (var methodInfo in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                {
                    var interceptAttributes = methodInfo.IsDefined(InterceptAttributeType, false)
                        ? Merge(attributes, methodInfo.GetCustomAttributesData())
                        : attributes;

                    if (interceptAttributes.Count == 0)
                    {
                        continue;
                    }

                    if (interceptMethods.TryGetValue(methodInfo, out var intercepts))
                    {
                        interceptMethods[methodInfo] = Merge(intercepts, interceptAttributes);
                    }
                    else
                    {
                        interceptMethods.Add(methodInfo, interceptAttributes);
                    }
                }
            }

            var propertyMethods = new HashSet <MethodInfo>();

            foreach (var propertyInfo in serviceType.GetProperties())
            {
                var propertyEmitter = classEmitter.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType);

                if (propertyInfo.CanRead)
                {
                    var readMethod = propertyInfo.GetGetMethod(true);

                    propertyMethods.Add(readMethod);

                    propertyEmitter.SetGetMethod(InterceptCore.DefineMethodOverride(instanceAst, classEmitter, readMethod, new CustomAttributeData[0]));
                }

                if (propertyInfo.CanWrite)
                {
                    var writeMethod = propertyInfo.GetSetMethod(true);

                    propertyMethods.Add(writeMethod);

                    propertyEmitter.SetSetMethod(InterceptCore.DefineMethodOverride(instanceAst, classEmitter, writeMethod, new CustomAttributeData[0]));
                }
            }

            foreach (var methodInfo in serviceType.GetMethods())
            {
                if (propertyMethods.Contains(methodInfo))
                {
                    continue;
                }

                if (interceptMethods.TryGetValue(methodInfo, out var interceptAttributes))
                {
                    InterceptCore.DefineMethodOverride(instanceAst, classEmitter, methodInfo, interceptAttributes);
                }
                else
                {
                    InterceptCore.DefineMethodOverride(instanceAst, classEmitter, methodInfo, new CustomAttributeData[0]);
                }
            }

            propertyMethods.Clear();

            interceptMethods.Clear();

            return(Resolve(serviceType, classEmitter.CreateType(), lifetime));
        }
Пример #3
0
        public void TestLinq()
        {
#if NET461
            var m = new ModuleEmitter(true);
#else
            var m = new ModuleEmitter();
#endif
            var classType = m.DefineType("linq", TypeAttributes.Public);
            var method    = classType.DefineMethod("Query", MethodAttributes.Public, typeof(void));

            var pI = method.DefineParameter(typeof(int), ParameterAttributes.None, "i");
            var pJ = method.DefineParameter(typeof(int), ParameterAttributes.None, "j");

            var type = typeof(Entry);

            var arg         = Variable(typeof(ParameterExpression));
            var argProperty = Variable(typeof(MemberExpression));

            var callArg      = Call(typeof(Expression).GetMethod(nameof(Expression.Parameter), new Type[] { typeof(Type) }), Constant(type));
            var callProperty = Call(typeof(Expression).GetMethod(nameof(Expression.Property), new Type[] { typeof(Expression), typeof(string) }), arg, Constant("Id"));
            //var callBlock = Call(typeof(Expression).GetMethod(nameof(Expression.Block), new Type[] { typeof(IEnumerable<ParameterExpression>), typeof(IEnumerable<Expression>) }));

            method.Append(Assign(arg, callArg));
            method.Append(Assign(argProperty, callProperty));

            var variable_variables = Variable(typeof(ParameterExpression[]));

            var variables = NewArray(1, typeof(ParameterExpression));

            method.Append(Assign(variable_variables, variables));

            method.Append(Assign(ArrayIndex(variable_variables, 0), arg));

            var constantI = Call(typeof(Expression).GetMethod(nameof(Expression.Constant), new Type[] { typeof(object) }), Convert(pI, typeof(object)));

            var equalMethod = Call(typeof(Expression).GetMethod(nameof(Expression.Equal), new Type[] { typeof(Expression), typeof(Expression) }), argProperty, constantI);

            var lamdaMethod = typeof(Tests).GetMethod(nameof(Tests.Lambda))
                              .MakeGenericMethod(typeof(Func <Entry, bool>));

            var whereLambda = Variable(typeof(Expression <Func <Entry, bool> >));

            method.Append(Assign(whereLambda, Call(lamdaMethod, equalMethod, variable_variables)));

            method.Append(ReturnVoid());

            classType.CreateType();
#if NET461
            m.SaveAssembly();
#endif

            // 生成代码如下:

            /**
             * public void Query(int i, int j)
             * {
             *      ParameterExpression parameterExpression = Expression.Parameter(typeof(Entry));
             *      MemberExpression left = Expression.Property(parameterExpression, "Id");
             *      Expression<Func<Entry, bool>> expression = Tests.Lambda<Func<Entry, bool>>(parameters: new ParameterExpression[1]
             *      {
             *              parameterExpression
             *      }, body: Expression.Equal(left, Expression.Constant(i)));
             * }
             */
        }