Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本
Dora.Interception 1.0(可以訪問GitHub地址:https://github.com/jiangjinnan/Dora)推出有一段時間了,最近花了點時間將它升級到2.0,主要有如下的改進:
提供了原生的動態代理生成底層框架Dora.DynamicProxy:之前依賴第三方框架Castle實現最底層的代理生成,但是它不支持基于Task的并行編程(也就是說通過它編寫的Interceptor無法實現異步執行),所以我采用IL Emit的方式自行實現了這部分的功能,這些底層的功能實現在Dora.DynamicProxy中。
提供了如下兩種形式的攔截方案:
基于實例封裝:如果消費的類型是一個接口,那么提供的類型為動態生成的代理類,該代理類封裝了目標對象。對于每一個動態生成的接口實現成員來說,它會負責執行應用的Interceptor。如果需要調用目標方法,被封裝的目標對象的對應方法會被調用。這種攔截方案要求目標類型實現一個接口,接口中定義的所有方法和屬性都是可以被攔截的。
基于類型繼承:如果目標類型是一個非Sealed類型,一個繼承與它的代理類型會被動態生成。如果Interceptor被應用到目標類型的某個虛方法或者屬性上,該成員會在生成的代理類中被重寫,進而使Interceptor得以執行。這種攔截機制適合非Sealed類型,只有虛方法/屬性能夠被攔截。
提供了針對屬性的攔截支持:之前的版本支持針對方法的攔截,最新版本中提供了針對屬性的攔截支持。我們可以選擇將Interceptor應用到某個類型的屬性上,也可以單獨應用到該屬性的Get或者Set方法上。
一、對基于Task的并行編程的支持
由于Dora.Interception將Dora.DynamicProxy作為默認的動態代理類型生成框架,所以不在依賴任何第三發框架,因此在編程會變得更加簡單,現在我們來做一個簡單的演示。在安裝了最新版本的NuGet包Dora.Interception之后,我們可以按照 “約定” 的方式來定義如下這么一個簡單的Interceptor類型。為了驗證針對Task并行編程的支持,我們特意在攔截方法InvokeAsync中Delay了一秒鐘。
public class FoobarInterceptor { ? ?private InterceptDelegate _next; ?
?public FoobarInterceptor(InterceptDelegate next){_next = next;} ?
?public async Task InvokeAsync(InvocationContext context){Console.WriteLine("Interception task starts."); ? ? ?
?await Task.Delay(1000);Console.WriteLine("Interception task completes."); ?
? ? ?await _next(context);} }
我將Interceptor和Interceptor的注冊特意區分開來,Interceptor的注冊默認采用特性標注的形式來實現,為此我們為上面定義的FoobarInterceptor創建一個對應的特性類型FoobarAttribute。如下面的代碼片段所示,FoobarAttribute派生于InterceptorAttribute,FoobarInterceptor在重寫的Use方法中被構建,在構建過程中可以指定該Interceptor在整個Interceptor Chain的位置(Order)。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property)] public class FoobarAttribute : InterceptorAttribute { ? ?public override void Use(IInterceptorChainBuilder builder){builder.Use<FoobarInterceptor>(this.Order);} }
接下來我們定義了簡單的類型Demo來使用FoobarInterceptor,Demo實現了接口IDemo,FoobarAttribute標注在需要被攔截的方法InvokeAsync上。
public interface IDemo {Task InvokeAsync(); }public class Demo : IDemo {[Foobar] ? ?
public Task InvokeAsync(){Console.WriteLine("Target method is invoked."); ? ? ?
?return Task.CompletedTask;} }
由于Dora.Interception實現了與.NET Core的Dependency Injection的無縫集成,所以我們只需要采用我們熟悉的方式來提供服務實例就可以了。如下面的代碼片段所示,我們將IDemo和Demo之間的映射關系注冊到創建的ServiceCollection上之后,并沒有調用BuildeServiceProvider方法,而是調用BuildInterceptableServiceProvider來創建提供服務的ServiceProvider。
class Program {static void Main(string[] args){ ? ? ? ?var demo = new ServiceCollection().AddSingleton<IDemo, Demo>() .BuildeInterceptableServiceProvider().GetRequiredService<IDemo>(); ?demo.InvokeAsync();Console.WriteLine("Continue...");Console.Read();} }
如下所示的是這段代碼的執行結果,我們可以看到應用的FoobarInterceptor被正常執行,而且它完全是以異步的方式執行的。
二、基于虛方法的攔截
如果Demo沒有實現任何的接口,并且它不是一個Sealed類型,它的虛方法和屬性也是可以被攔截的。比如我們將Demo做了如下的改動。
public class Demo {[Foobar] ??public virtual Task InvokeAsync(){Console.WriteLine("Target method is invoked."); ? ?
? ?return Task.CompletedTask;} }
所有Demo沒有了接口實現,所以我們需要對服務注冊代碼做相應的修改。執行修后的代碼,我們依然會得到相同的輸出。
class Program { ? ?static void Main(string[] args){ ? ? ? ?var demo = new ServiceCollection().AddSingleton<Demo, Demo>() .BuildeInterceptableServiceProvider().GetRequiredService<Demo>(); ?demo.InvokeAsync();Console.WriteLine("Continue...");Console.Read();} }三、屬性也可被攔截
對于上一版本來說,被攔截的成員僅限于普通的方法,最新的版本增加對屬性的支持。如果一個Interceptor被直接應用到某個屬性上,它實際上會被同時應用到該屬性的Get和Set方法上。比如我們在Demo類型上添加一個Value屬性,并在上面標準FoobarAttribute。
public class Demo {[Foobar] ? ?public virtual object Value { get; set; } }接下來我們按照如下的方式獲取一個Demo對象,并調用其Value屬性的Set和Get方法。
class Program { ??static void Main(string[] args){ ? ? ? ?var demo = new ServiceCollection().AddSingleton<Demo, Demo>().BuildInterceptableServiceProvider().GetRequiredService<Demo>();Console.WriteLine("Set...");demo.Value = new object();Console.WriteLine("Get..."); ? ? ?
?var value = demo.Value;Console.Read();} }
從如下的輸出結果可以看出,我們注冊到Value屬性上的FoobarInterceptor在Get和Set方法被調用的時候都執行了一遍。
如果我們只需要在某個屬性的Get或者Set方法上應用某個Interceptor,我們也可以作針對性的標注。在如下的代碼片段中,我們將FoobarAttrbute標準到Get方法上。
public class Demo { ??public virtual object Value { [Foobar] get; set; } }
再次執行程序,我們會發現FoobarInterceptor僅僅在調用Value屬性的Get方法時被執行了一次。
原文地址:https://www.cnblogs.com/artech/p/dora2-01.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小白带你入坑xamarin系列之环境搭建
- 下一篇: Quartz.Net分布式任务管理平台