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 }
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)); }
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))); * } */ }