日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET 下基于动态代理的 AOP 框架实现揭秘

發布時間:2023/12/4 asp.net 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET 下基于动态代理的 AOP 框架实现揭秘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

.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 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 來創建代理

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

使用示例:

var testService = ProxyGenerator.Instance.CreateInterfaceProxy<ITestService>(); testService.Test();

可以看到這個類型就是我們動態創建的一個類型,輸出結果也是我們定義在代理類中的結果

More

.NET 中的基于動態代理的 AOP 也是這樣實現的,實現的原理大致就是這樣,這個示例比較簡單還沒有涉及 AOP ,這只是一個簡單的動態代理示例 ,AOP 只需要在原始方法執行的邏輯上包裝一層攔截器增加對攔截器的處理和調用即可,暫時還沒實現,后面有機會再分享

Reference

  • https://github.com/dotnetcore/AspectCore-Framework

  • https://github.com/dotnetcore/AspectCore-Framework/blob/master/src/AspectCore.Core/Utils/ProxyGeneratorUtils.cs

  • https://github.com/castleproject/Core

  • https://github.com/castleproject/Core/blob/master/src/Castle.Core/DynamicProxy/ModuleScope.cs

  • https://github.com/dotnet/runtime/blob/master/src/libraries/System.Reflection.DispatchProxy/src/System/Reflection/DispatchProxyGenerator.cs

  • https://github.com/WeihanLi/SamplesInPractice/blob/master/AopSample/Program.cs

總結

以上是生活随笔為你收集整理的.NET 下基于动态代理的 AOP 框架实现揭秘的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。