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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FluentAspects -- 基于 Fluent API 的 Aop

發布時間:2023/12/4 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FluentAspects -- 基于 Fluent API 的 Aop 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

FluentAspects -- 基于 Fluent API 的 Aop

Intro

上次我們做了一個簡單的 AOP 實現示例,但是實現起來主要是基于 Attribute 來做的,對于代碼的侵入性太強,于是嘗試實現基于 Fluent API 的方式來做 AOP 。

抽象 InterceptorResolver

原來獲取方法執行的 Interceptor 是通過 Attribute 來獲取的,現在我們只需要將獲取 Interceptor 的邏輯抽象出來就可以實現不必依賴于 Attribute 了

方法執行上下文定義:

public interface IInvocation {public MethodInfo ProxyMethod { get; }public object ProxyTarget { get; }public MethodInfo Method { get; }public object Target { get; }public object[] Arguments { get; }Type[] GenericArguments { get; }public object ReturnValue { get; set; } }

方法攔截器 Interceptor 接口定義:

public interface IInterceptor {Task Invoke(IInvocation invocation, Func<Task> next); }

自定義 Interceptor 只需要繼承這個接口實現相應的邏輯就好了

獲取 IInterceptorResolver 接口定義:

public interface IInterceptorResolver {IReadOnlyCollection<IInterceptor> ResolveInterceptors(IInvocation invocation); }

原來基于 Attribute 獲取 Interceptor 的方式可以實現一個 AttributeInterceptorResolver

想要基于 Fluent API 來獲取 Interceptor ,只需要實現基于 Fluent API 的 InterceptorResolver 就可以了,具體的實現可以參考 FluentConfigInterceptorResolver

示例預覽

測試服務定義:

public interface ISvc1 {void Invoke(); } public interface ISvc2 {void Invoke(); } public class Svc2 : ISvc2 {public void Invoke(){Console.WriteLine($"invoking in {GetType().Name} ...");}public void Invoke2(){Console.WriteLine($"invoking in {GetType().Name} ...");} } public class Svc3 {public virtual void Invoke(){Console.WriteLine($"invoking in {GetType().Name} ...");} } public class Svc4 {public virtual void Invoke(){Console.WriteLine($"invoking in {GetType().Name} ...");}public void Invoke2(){Console.WriteLine($"invoking2 in {GetType().Name} ...");}public virtual void Invoke3(){Console.WriteLine($"invoking3 in {GetType().Name} ...");} }

測試 Interceptor

internal class LogInterceptor : IInterceptor {public async Task Invoke(IInvocation invocation, Func<Task> next){Console.WriteLine($"invoke {invocation.ProxyMethod} in {GetType().Name} begin");await next();Console.WriteLine($"invoke {invocation.ProxyMethod} in {GetType().Name} end");} }

測試代碼:

public static void Main(string[] args) {var services = new ServiceCollection();services.AddFluentAspects(options =>{// 為所有攔截的方法添加攔截器options.InterceptAll().With<LogInterceptor>();// 對 Svc3 類型禁用攔截器options.NoInterceptType<Svc3>();// Svc4 類型的 Invoke3() 方法禁用攔截器options.NoInterceptMethod<Svc4>(s => s.Invoke3());});services.AddTransientProxy<Svc4>();var serviceProvider = services.BuildServiceProvider();var proxyFactory = serviceProvider.GetRequiredService<IProxyFactory>();var svc1 = proxyFactory.CreateProxy<ISvc1>();svc1.Invoke();Console.WriteLine();var svc2 = proxyFactory.CreateProxy<ISvc2, Svc2>();svc2.Invoke();Console.WriteLine();var svc3 = proxyFactory.CreateProxy<Svc3>();svc3.Invoke();Console.WriteLine();var svc4 = proxyFactory.CreateProxyWithTarget<ISvc2, Svc2>(new Svc2());svc4.Invoke();Console.WriteLine();// 直接從注冊的服務中獲取var svc5 = serviceProvider.GetRequiredService<Svc4>();svc5.Invoke();Console.WriteLine();svc5.Invoke2();Console.WriteLine();svc5.Invoke3();Console.WriteLine();Console.WriteLine("finished");Console.ReadLine(); }

輸出結果預覽:

More

最近十幾天的時間一直在搞這個,相比之前寫的示例,真正實現一個完整的 AOP 框架還是要做比較多的事情的,之前的 AOP 示例,沒有考慮泛型,也沒有什么設計,所以前面的示例只能算是一個小玩具。

在實現的過程中,參考了很多 AspectCore 的代碼,有一些代碼甚至是直接從 AspectCore 里抄過來的。

推薦大家有機會研究學習一下檸檬大佬的 AspectCore 的源碼,這個 AOP 框架的代碼組織,代碼細節都挺不錯的。

AspectCore 源碼地址:https://github.com/dotnetcore/AspectCore-Framework

Reference

  • https://github.com/WeihanLi/WeihanLi.Common/tree/dev/src/WeihanLi.Common/Aspect

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

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

總結

以上是生活随笔為你收集整理的FluentAspects -- 基于 Fluent API 的 Aop的全部內容,希望文章能夠幫你解決所遇到的問題。

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