public ProxyByImplementationType(ModuleEmitter moduleEmitter, Type serviceType, Type implementationType, ServiceLifetime lifetime) { this.moduleEmitter = moduleEmitter; this.serviceType = serviceType; this.implementationType = implementationType; this.lifetime = lifetime; }
private RuntimeModule EmitAndSaveModule(string name, BoundStatementBlock body) { ModuleEmitter emitter = new ModuleEmitter(body); RuntimeModule module = new RuntimeModule(name, emitter.Instructions, body.Syntax); this.Modules.Add(module.Name, module); return(module); }
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 }
/// <summary> /// 使用拦截器。 /// 为标记了 <see cref="InterceptAttribute"/> 的接口、类或方法生成代理类。 /// </summary> /// <param name="services">服务集合。</param> /// <returns></returns> public static IServiceCollection UseMiddleware(this IServiceCollection services) { if (services is null) { throw new ArgumentNullException(nameof(services)); } #if NET40_OR_GREATER && DEBUG var moduleEmitter = new ModuleEmitter(true); #else var moduleEmitter = new ModuleEmitter(); #endif for (int i = 0; i < services.Count; i++) { ServiceDescriptor descriptor = services[i]; if (!Intercept(descriptor)) { continue; } IProxyByPattern byPattern; if (descriptor.ImplementationType is null) { if (descriptor.ImplementationInstance is null) { byPattern = new ProxyByInstance(moduleEmitter, descriptor.ServiceType, descriptor.ImplementationInstance); } else { byPattern = new ProxyByFactory(moduleEmitter, descriptor.ServiceType, descriptor.ImplementationFactory, descriptor.Lifetime); } } else { byPattern = new ProxyByImplementationType(moduleEmitter, descriptor.ServiceType, descriptor.ImplementationType, descriptor.Lifetime); } services[i] = byPattern.Resolve(); } #if NET40_OR_GREATER && DEBUG moduleEmitter.SaveAssembly(); #endif return(services); }
public ProxyByServiceType(ModuleEmitter moduleEmitter, Type serviceType, ServiceLifetime lifetime) { this.moduleEmitter = moduleEmitter; this.serviceType = serviceType; this.lifetime = lifetime; }
public ProxyByInstance(ModuleEmitter moduleEmitter, Type serviceType, object instance) : base(moduleEmitter, serviceType, ServiceLifetime.Singleton) { this.instance = instance ?? throw new ArgumentNullException(nameof(instance)); }
public ProxyByFactory(ModuleEmitter moduleEmitter, Type serviceType, Func <IServiceProvider, object> implementationFactory, ServiceLifetime lifetime) : base(moduleEmitter, serviceType, lifetime) { this.implementationFactory = implementationFactory ?? throw new ArgumentNullException(nameof(implementationFactory)); }
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))); * } */ }