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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本

發(fā)布時(shí)間:2023/12/4 asp.net 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Dora.Interception 1.0(可以訪問GitHub地址:https://github.com/jiangjinnan/Dora)推出有一段時(shí)間了,最近花了點(diǎn)時(shí)間將它升級(jí)到2.0,主要有如下的改進(jìn):

  • 提供了原生的動(dòng)態(tài)代理生成底層框架Dora.DynamicProxy:之前依賴第三方框架Castle實(shí)現(xiàn)最底層的代理生成,但是它不支持基于Task的并行編程(也就是說通過它編寫的Interceptor無法實(shí)現(xiàn)異步執(zhí)行),所以我采用IL Emit的方式自行實(shí)現(xiàn)了這部分的功能,這些底層的功能實(shí)現(xiàn)在Dora.DynamicProxy中。

  • 提供了如下兩種形式的攔截方案:

    • 基于實(shí)例封裝:如果消費(fèi)的類型是一個(gè)接口,那么提供的類型為動(dòng)態(tài)生成的代理類,該代理類封裝了目標(biāo)對象。對于每一個(gè)動(dòng)態(tài)生成的接口實(shí)現(xiàn)成員來說,它會(huì)負(fù)責(zé)執(zhí)行應(yīng)用的Interceptor。如果需要調(diào)用目標(biāo)方法,被封裝的目標(biāo)對象的對應(yīng)方法會(huì)被調(diào)用。這種攔截方案要求目標(biāo)類型實(shí)現(xiàn)一個(gè)接口,接口中定義的所有方法和屬性都是可以被攔截的。

    • 基于類型繼承:如果目標(biāo)類型是一個(gè)非Sealed類型,一個(gè)繼承與它的代理類型會(huì)被動(dòng)態(tài)生成。如果Interceptor被應(yīng)用到目標(biāo)類型的某個(gè)虛方法或者屬性上,該成員會(huì)在生成的代理類中被重寫,進(jìn)而使Interceptor得以執(zhí)行。這種攔截機(jī)制適合非Sealed類型,只有虛方法/屬性能夠被攔截。

  • 提供了針對屬性的攔截支持:之前的版本支持針對方法的攔截,最新版本中提供了針對屬性的攔截支持。我們可以選擇將Interceptor應(yīng)用到某個(gè)類型的屬性上,也可以單獨(dú)應(yīng)用到該屬性的Get或者Set方法上。

一、對基于Task的并行編程的支持

由于Dora.Interception將Dora.DynamicProxy作為默認(rèn)的動(dòng)態(tài)代理類型生成框架,所以不在依賴任何第三發(fā)框架,因此在編程會(huì)變得更加簡單,現(xiàn)在我們來做一個(gè)簡單的演示。在安裝了最新版本的NuGet包Dora.Interception之后,我們可以按照 “約定” 的方式來定義如下這么一個(gè)簡單的Interceptor類型。為了驗(yàn)證針對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的注冊特意區(qū)分開來,Interceptor的注冊默認(rèn)采用特性標(biāo)注的形式來實(shí)現(xiàn),為此我們?yōu)樯厦娑x的FoobarInterceptor創(chuàng)建一個(gè)對應(yīng)的特性類型FoobarAttribute。如下面的代碼片段所示,FoobarAttribute派生于InterceptorAttribute,FoobarInterceptor在重寫的Use方法中被構(gòu)建,在構(gòu)建過程中可以指定該Interceptor在整個(gè)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實(shí)現(xiàn)了接口IDemo,FoobarAttribute標(biāo)注在需要被攔截的方法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實(shí)現(xiàn)了與.NET Core的Dependency Injection的無縫集成,所以我們只需要采用我們熟悉的方式來提供服務(wù)實(shí)例就可以了。如下面的代碼片段所示,我們將IDemo和Demo之間的映射關(guān)系注冊到創(chuàng)建的ServiceCollection上之后,并沒有調(diào)用BuildeServiceProvider方法,而是調(diào)用BuildInterceptableServiceProvider來創(chuàng)建提供服務(wù)的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();} }

如下所示的是這段代碼的執(zhí)行結(jié)果,我們可以看到應(yīng)用的FoobarInterceptor被正常執(zhí)行,而且它完全是以異步的方式執(zhí)行的。

二、基于虛方法的攔截

如果Demo沒有實(shí)現(xiàn)任何的接口,并且它不是一個(gè)Sealed類型,它的虛方法和屬性也是可以被攔截的。比如我們將Demo做了如下的改動(dòng)。

public class Demo {[Foobar] ?
?public virtual Task InvokeAsync(){Console.WriteLine("Target method is invoked."); ? ?
? ?return Task.CompletedTask;} }

所有Demo沒有了接口實(shí)現(xiàn),所以我們需要對服務(wù)注冊代碼做相應(yīng)的修改。執(zhí)行修后的代碼,我們依然會(huì)得到相同的輸出。

class Program { ? ?static void Main(string[] args){ ? ? ? ?var demo = new ServiceCollection().AddSingleton<Demo, Demo>() .BuildeInterceptableServiceProvider().GetRequiredService<Demo>(); ?demo.InvokeAsync();Console.WriteLine("Continue...");Console.Read();} }

三、屬性也可被攔截

對于上一版本來說,被攔截的成員僅限于普通的方法,最新的版本增加對屬性的支持。如果一個(gè)Interceptor被直接應(yīng)用到某個(gè)屬性上,它實(shí)際上會(huì)被同時(shí)應(yīng)用到該屬性的Get和Set方法上。比如我們在Demo類型上添加一個(gè)Value屬性,并在上面標(biāo)準(zhǔn)FoobarAttribute。

public class Demo {[Foobar] ? ?public virtual object Value { get; set; } }

接下來我們按照如下的方式獲取一個(gè)Demo對象,并調(diào)用其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();} }

從如下的輸出結(jié)果可以看出,我們注冊到Value屬性上的FoobarInterceptor在Get和Set方法被調(diào)用的時(shí)候都執(zhí)行了一遍。

如果我們只需要在某個(gè)屬性的Get或者Set方法上應(yīng)用某個(gè)Interceptor,我們也可以作針對性的標(biāo)注。在如下的代碼片段中,我們將FoobarAttrbute標(biāo)準(zhǔn)到Get方法上。

public class Demo { ?
?public virtual object Value { [Foobar] get; set; } }

再次執(zhí)行程序,我們會(huì)發(fā)現(xiàn)FoobarInterceptor僅僅在調(diào)用Value屬性的Get方法時(shí)被執(zhí)行了一次。

原文地址:https://www.cnblogs.com/artech/p/dora2-01.html


.NET社區(qū)新聞,深度好文,歡迎訪問公眾號(hào)文章匯總 http://www.csharpkit.com

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Dora.Interception,为.NET Core度身打造的AOP框架:全新的版本的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。