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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Autofac的切面编程实现

發布時間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Autofac的切面编程实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

面向切面編程:Autofac.Annotation擴展組件是我開源的一款利用打標簽完成autofac容器的注入組件。

https://github.com/yuzd/Autofac.Annotation

我們之前介紹了利用Aspect標簽來完成攔截器功能

Aspect是一對一的方式,我想要某個class開啟攔截器功能我需要針對每個class去配置。?詳情請點擊

比如說 我有2個 controller 每個controller都有2個action方法,

[Component]public class ProductController{public virtual string GetProduct(string productId){return "GetProduct:" + productId;}public virtual string UpdateProduct(string productId){return "UpdateProduct:" + productId;}}[Component]public class UserController{public virtual string GetUser(string userId){return "GetUser:" + userId;}public virtual string DeleteUser(string userId){return "DeleteUser:" + userId;}}

如果我需要這2個controller的action方法都在執行方法前打log 在方法執行后打log 按照上一節Aspect的話 我需要每個controller都要配置。如果我有100個controller的畫我就需要配置100次,這樣我覺得太麻煩了。所以我參考了Spring的Pointcut切面編程的方式實現了一套類似的,下面看如何用Pointcut的方式方便的配置一種切面去適用于N個對象。

定義一個切面:創建一個class 上面打上Pointcut的標簽 如下:

Pointcut標簽類有如下屬性:

屬性名說明
Name名稱Pointcut切面的名稱(默認為空,和攔截方法進行匹配,參考下面說明)
RetType匹配目標類的方法的返回類型(默認是%)
NameSpace匹配目標類的namespace(默認是%)
ClassName匹配目標類的類名稱(必填)
MethodName匹配目標類的方法名稱(默認是%)

匹配算法

?舉例:

匹配結果匹配模板要匹配的字符串
匹配結果:true"%"""
匹配結果:true"%"" "
匹配結果:true"%""asdfa asdf asdf"
匹配結果:true"%""%"
匹配結果:false"_"""
匹配結果:true"_"" "
匹配結果:true"_""4"
匹配結果:true"_""C"
匹配結果:false"_""CX"
匹配結果:false"[ABCD]"""
匹配結果:true"[ABCD]""A"
匹配結果:true"[ABCD]""b"
匹配結果:false"[ABCD]""X"
匹配結果:false"[ABCD]""AB"
匹配結果:true"[B-D]""C"
匹配結果:true"[B-D]""D"
匹配結果:false"[B-D]""A"
匹配結果:false"[^B-D]""C"
匹配結果:false"[^B-D]""D"
匹配結果:true"[^B-D]""A"
匹配結果:true"%TEST[ABCD]XXX""lolTESTBXXX"
匹配結果:false"%TEST[ABCD]XXX""lolTESTZXXX"
匹配結果:false"%TEST[^ABCD]XXX""lolTESTBXXX"
匹配結果:true"%TEST[^ABCD]XXX""lolTESTZXXX"
匹配結果:true"%TEST[B-D]XXX""lolTESTBXXX"
匹配結果:true"%TEST[^B-D]XXX""lolTESTZXXX"
匹配結果:true"%Stuff.txt""Stuff.txt"
匹配結果:true"%Stuff.txt""MagicStuff.txt"
匹配結果:false"%Stuff.txt""MagicStuff.txt.img"
匹配結果:false"%Stuff.txt""Stuff.txt.img"
匹配結果:false"%Stuff.txt""MagicStuff001.txt.img"
匹配結果:true"Stuff.txt%""Stuff.txt"
匹配結果:false"Stuff.txt%""MagicStuff.txt"
匹配結果:false"Stuff.txt%""MagicStuff.txt.img"
匹配結果:true"Stuff.txt%""Stuff.txt.img"
匹配結果:false"Stuff.txt%""MagicStuff001.txt.img"
匹配結果:true"%Stuff.txt%""Stuff.txt"
匹配結果:true"%Stuff.txt%""MagicStuff.txt"
匹配結果:true"%Stuff.txt%""MagicStuff.txt.img"
匹配結果:true"%Stuff.txt%""Stuff.txt.img"
匹配結果:false"%Stuff.txt%""MagicStuff001.txt.img"
匹配結果:true"%Stuff%.txt""Stuff.txt"
匹配結果:true"%Stuff%.txt""MagicStuff.txt"
匹配結果:false"%Stuff%.txt""MagicStuff.txt.img"
匹配結果:false"%Stuff%.txt""Stuff.txt.img"
匹配結果:false"%Stuff%.txt""MagicStuff001.txt.img"
匹配結果:true"%Stuff%.txt""MagicStuff001.txt"
匹配結果:true"Stuff%.txt%""Stuff.txt"
匹配結果:false"Stuff%.txt%""MagicStuff.txt"
匹配結果:false"Stuff%.txt%""MagicStuff.txt.img"
匹配結果:true"Stuff%.txt%""Stuff.txt.img"
匹配結果:false"Stuff%.txt%""MagicStuff001.txt.img"
匹配結果:false"Stuff%.txt%""MagicStuff001.txt"
匹配結果:true"%Stuff%.txt%""Stuff.txt"
匹配結果:true"%Stuff%.txt%""MagicStuff.txt"
匹配結果:true"%Stuff%.txt%""MagicStuff.txt.img"
匹配結果:true"%Stuff%.txt%""Stuff.txt.img"
匹配結果:true"%Stuff%.txt%""MagicStuff001.txt.img"
匹配結果:true"%Stuff%.txt%""MagicStuff001.txt"
匹配結果:true"?Stuff?.txt?""1Stuff3.txt4"
匹配結果:false"?Stuff?.txt?""1Stuff.txt4"
匹配結果:false"?Stuff?.txt?""1Stuff3.txt"
匹配結果:false"?Stuff?.txt?""Stuff3.txt4"
// *Controller 代表匹配 只要是Controller結尾的類都能匹配// Get* 代表上面匹配成功的類下 所以是Get打頭的方法都能匹配[Pointcut(ClassName = "*Controller",MethodName = "Get*")]public class LoggerPointCut{}

定義好了一個Pointcut切面后 需要定義這個切面的攔截方法

配合Pointcut切面標簽,可以在打了這個標簽的class下定義攔截方法, 在方法上得打上特定的標簽,有如下幾種:

切面執行方法上打標簽種類說明
Before標簽在匹配成功的類的方法執行前執行
After標簽在匹配成功的類的方法執行后執行
Around標簽承接了 匹配成功的類的方法的執行權(如果一個切面配置了Around又配置了Before或者After,那么會只執行Around)

以上3種標簽有一個可選的參數:Name (默認為空,可以和Pointcut的Name進行mapping)

  • 因為一個class上可以打多個Pointcut切面,一個Pointcut切面可以根據name去匹配對應攔截方法

// *Controller 代表匹配 只要是Controller結尾的類都能匹配// Get* 代表上面匹配成功的類下 所以是Get打頭的方法都能匹配[Pointcut(ClassName = "*Controller",MethodName = "Get*")]public class LoggerPointCut{/// <summary>/// 打上Before標簽 代表滿足匹配的方法 在執行之前會執行下面的Before()方法/// </summary>[Before]public void Befor(){Console.WriteLine("before");}/// <summary>/// 打上After標簽 代表滿足匹配的方法 在執行之前會執行下面的After()方法/// </summary>[After]public void After(){Console.WriteLine("after");}}

如果是用Around環繞的話

// *Controller 代表匹配 只要是Controller結尾的類都能匹配// Get* 代表上面匹配成功的類下 所以是Get打頭的方法都能匹配[Pointcut(ClassName = "*Controller",MethodName = "Get*")]public class LoggerPointCut{/// <summary>/// 打上Around標簽 承接了 匹配成功的類的方法的執行權/// </summary>/// <param name="context"></param>[Around]public void Around(AspectContext context){//執行原目標方法前Console.WriteLine(context.InvocationContext.MethodInvocationTarget.Name + "-->Start");//執行原目標方法context.InvocationProceedInfo.Invoke();//執行原目標方法后Console.WriteLine(context.InvocationContext.MethodInvocationTarget.Name + "-->End");}}

執行方法的參數說明:

執行方法的參數可以是DI容器的類型,會在執行時自動注入進來,可以使用Autowired,Value等標簽來修飾參數。

還有一個特殊的執行參數可以注入,那就是AspectContext,這個類型里面你可以獲取到被攔截的方法的信息,以及執行原方法的委托。

注意:這個執行后 有2種

  • 正常執行成功

  • 有異常,若方法參數注入了AspectContext 那么可以通過Exception屬性值獲得異常內容

按照上面的配置

  • ProductController.GetProduct 會被匹配

  • UserController.GetUser 會被匹配

在執行上面這2個方法的時候會

  • 先執行 LoggerPointCut.Before方法

  • 再執行 LoggerPointCut.After方法

利用Autofac的這個開源擴展組件很方便的實現切面編程,總結切面編程三步驟

  • 1.定義一個切面,編寫要匹配的目標類的方法(采用sql的like方式匹配),所以一個切面可以攔截n個目標

  • 2.定義對應的攔截方法

  • 3.執行被匹配的方法時會執行對應的攔截方法

總結

以上是生活随笔為你收集整理的Autofac的切面编程实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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