以前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的能够看这篇文章 https://www.cnblogs.com/weihanli/p/roslyn-based-condition-eval-engine.htmlhtml
执行过程当中会根据条件的不一样会在运行时建立一个类,每一次建立都会生成一个新的程序集,我以为这样实现的话可能会致使加载的程序集愈来愈多,虽然目前咱们的使用场景下不会有不少,并且相同的条件只会生成一次,仍是以为这样不是特别好,此时想起来了一些 AOP 框架,Aspect.Core
/Castle
/DispatchProxy
,他们这些 AOP 框架会生成一些代码类,好像也没有生成不少额外的程序集,因而打算看看这些 AOP 框架的实现,看看它们是如何生成动态代理类的git
看了这三个 AOP 框架的实现代码以后,实现原理基本都是同样的github
都是经过建立一个 DynamicAssembly
以后在这个 DynamicAssemly
中建立要动态生成代理类,经过 Emit 建立要生成动态代理类的方法/属性等框架
多说不如来点代码示例:ide
internal class ProxyUtil { private const string ProxyAssemblyName = "Aop.DynamicGenerated"; private static readonly ModuleBuilder _moduleBuilder; private static readonly ConcurrentDictionary<string, Type> _proxyTypes = new ConcurrentDictionary<string, Type>(); static ProxyUtil() { // 定义一个动态程序集 var asmBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(ProxyAssemblyName), AssemblyBuilderAccess.Run); // 建立一个动态模块,后面建立动态代理类经过这个来建立 _moduleBuilder = asmBuilder.DefineDynamicModule("Default"); } public static Type CreateInterfaceProxy(Type interfaceType) { var proxyTypeName = $"{ProxyAssemblyName}.{interfaceType.FullName}"; var type = _proxyTypes.GetOrAdd(proxyTypeName, name => { // 定义要建立的类型,并实现指定类型接口 var typeBuilder = _moduleBuilder.DefineType(proxyTypeName, TypeAttributes.Public, typeof(object), new[] { interfaceType }); // 定义一个默认的构造方法 typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); // 获取接口中定义的方法 var methods = interfaceType.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (var method in methods) { // 在动态类中定义方法,方法名称,返回值和签名与接口方法保持一致 var methodBuilder = typeBuilder.DefineMethod(method.Name , MethodAttributes.Public | MethodAttributes.Virtual, method.CallingConvention, method.ReturnType, method.GetParameters() .Select(p => p.ParameterType) .ToArray() ); // 获取 ILGenerator,经过 Emit 实现方法体 var ilGenerator = methodBuilder.GetILGenerator(); ilGenerator.EmitWriteLine($"method [{method.Name}] is invoking..."); ilGenerator.Emit(OpCodes.Ret); // 定义方法实现 typeBuilder.DefineMethodOverride(methodBuilder, method); } return typeBuilder.CreateType(); }); return type; } }
经过上面的定义咱们能够建立一个简单的代理类,而后定义一个 ProxyGenerator
来建立代理ui
public class ProxyGenerator { public static readonly ProxyGenerator Instance = new ProxyGenerator(); public object CreateInterfaceProxy(Type interfaceType) { var type = ProxyUtil.CreateInterfaceProxy(interfaceType); return Activator.CreateInstance(type); } } // 定义泛型扩展 public static class ProxyGeneratorExtensions { public static TInterface CreateInterfaceProxy<TInterface>(this ProxyGenerator proxyGenerator) => (TInterface)proxyGenerator.CreateInterfaceProxy(typeof(TInterface)); }
使用示例:this
var testService = ProxyGenerator.Instance.CreateInterfaceProxy<ITestService>(); testService.Test();
能够看到这个类型就是咱们动态建立的一个类型,输出结果也是咱们定义在代理类中的结果spa
.NET 中的基于动态代理的 AOP 也是这样实现的,实现的原理大体就是这样,这个示例比较简单尚未涉及 AOP ,这只是一个简单的动态代理示例 ,AOP 只须要在原始方法执行的逻辑上包装一层拦截器增长对拦截器的处理和调用便可,暂时还没实现,后面有机会再分享代理