做的网站为什么看不到图片,雄安新区网站建设,网站成立时间,98建筑人才网.NET 下基于动态代理的 AOP 框架实现揭秘Intro之前基于 Roslyn 实现了一个简单的条件解析引擎#xff0c;想了解的可以看这篇文章 基于 Roslyn 实现一个简单的条件解析引擎执行过程中会根据条件的不同会在运行时创建一个类#xff0c;每一次创建都会生成一个新的程序集#… .NET 下基于动态代理的 AOP 框架实现揭秘Intro之前基于 Roslyn 实现了一个简单的条件解析引擎想了解的可以看这篇文章 基于 Roslyn 实现一个简单的条件解析引擎执行过程中会根据条件的不同会在运行时创建一个类每一次创建都会生成一个新的程序集我觉得这样实现的话可能会导致加载的程序集越来越多虽然目前我们的使用场景下不会有很多而且相同的条件只会生成一次还是觉得这样不是特别好此时想起来了一些 AOP 框架 Aspect.Core/ Castle/ DispatchProxy 他们这些 AOP 框架会生成一些代码类好像也没有生成很多额外的程序集于是打算看看这些 AOP 框架的实现看看它们是如何生成动态代理类的动态代理实现原理看了这三个 AOP 框架的实现代码之后实现原理基本都是一样的都是通过创建一个 DynamicAssembly 之后在这个 DynamicAssemly 中创建要动态生成代理类通过 Emit 创建要生成动态代理类的方法/属性等来个小示例多说不如来点代码示例internal class ProxyUtil
{private const string ProxyAssemblyName Aop.DynamicGenerated;private static readonly ModuleBuilder _moduleBuilder;private static readonly ConcurrentDictionarystring, Type _proxyTypes new ConcurrentDictionarystring, 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 来创建代理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 CreateInterfaceProxyTInterface(this ProxyGenerator proxyGenerator) (TInterface)proxyGenerator.CreateInterfaceProxy(typeof(TInterface));
}
使用示例var testService ProxyGenerator.Instance.CreateInterfaceProxyITestService();
testService.Test();
可以看到这个类型就是我们动态创建的一个类型输出结果也是我们定义在代理类中的结果More.NET 中的基于动态代理的 AOP 也是这样实现的实现的原理大致就是这样这个示例比较简单还没有涉及 AOP 这只是一个简单的动态代理示例 AOP 只需要在原始方法执行的逻辑上包装一层拦截器增加对拦截器的处理和调用即可暂时还没实现后面有机会再分享Referencehttps://github.com/dotnetcore/AspectCore-Frameworkhttps://github.com/dotnetcore/AspectCore-Framework/blob/master/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cshttps://github.com/castleproject/Corehttps://github.com/castleproject/Core/blob/master/src/Castle.Core/DynamicProxy/ModuleScope.cshttps://github.com/dotnet/runtime/blob/master/src/libraries/System.Reflection.DispatchProxy/src/System/Reflection/DispatchProxyGenerator.cshttps://github.com/WeihanLi/SamplesInPractice/blob/master/AopSample/Program.cs