1. 程式人生 > >.NET 簡易方法攔截器

.NET 簡易方法攔截器

parameter hid 接口 tle 說過 inf img 異常 肩膀

偉大的無產階級Willaim曾說過:"無論你覺得自己多麽的了不起,也永遠有人比你更強"。對,我說過!我就是william。

今天想記錄一下在項目中遇到的一個比較有意思的東西,異常攔截器(也不能完全說只是異常攔截,準確的說應該叫方法攔截),那有的人可能會說,異常攔截器不就是用Try……Catch就好了嗎?沒錯,Try……Catch是能攔截到異常。如果只是簡單攔截下,這種方法簡單可行。但是我們如果擴展下,所有的異常都要統一處理,如果你是架構師,你的團隊需要你提供一個公共的異常攔截處理組件,你會怎麽處理。

其實在做這個demo之前,我也是想了很多種處理方式,例如在方法前加特性頭使用AOP的方式,這種看的比較高大上,也需要配置大量config文件,比較復雜。也不適合我的項目現狀(實則是懶,由於框架已經基本形成,采用這種方式需要改動大量的已經完成的框架代碼,而且時間緊迫),所以放棄了。開始需求給到我時,一時之間無從下手,在網上搜羅很多處理方式,但大多數都是采用AOP加特性頭。當然我也這個demo也是借助於博客園中各位大神的經驗。站在巨人的肩膀上,我可以看得更遠!謝謝博客園的各位博主!矯情的話不多說了直接開始我的代碼之旅。

首先我們看看效果圖,俗話說沒圖說個J8,有圖有文的才是好博文。

技術分享圖片

(這是一張執行正常的截圖)

技術分享圖片

(這是一張執行帶有異常的截圖)

技術分享圖片

(demo的結構圖,只是簡單的模擬)

解釋一下工程結構圖每隔類文件的作用。其中紅框標記的是本次的重要組件,你的攔截器中需要用他中間的接口。Castle.Core我們可以在NuGet中進行安裝。

1.【MyIntercept.cs

這個文件就是自定義的攔截器。代碼很簡單。

技術分享圖片
 1 using Castle.DynamicProxy; //必須的
 2 
 3 
 4 public class MyIntercept : IInterceptor //需要實現這個接口(翻譯攔截)
 5 {
 6     public void Intercept(IInvocation invocation)
 7     {
 8        Console.WriteLine("【進入攔截器】");
 9        MethodInfo method = invocation.GetConcreteMethod();//
得到被攔截的方法 10 var parameter=invocation.Arguments[0].ToString();//獲取被攔截的方法參數 11 if (!invocation.MethodInvocationTarget.IsAbstract) 12 { 13 Console.WriteLine("【被攔截的方法執行前】"+method.Name+"的參數"+ parameter); 14 15 try 16 { 17 invocation.Proceed(); 18 } 19 catch (Exception ex) 20 { 21 22 Console.WriteLine("【攔截到異常】"+ex.Message); 23 } 24 Console.WriteLine("【被攔截的方法執結果】"+invocation.ReturnValue); 25 26 } 27 Console.WriteLine("【被攔截的方法執完畢】"); 28 } 29 }
View Code

2.ITestIntercept.cs

定義一個接口,接口中定義需要實現的方法,也就是需要被攔截的方法

技術分享圖片
1 public interface ITestIntercept
2  {
3         string Test(string p);
4 }
View Code

3.【TestIntercept.cs

實現上面的接口

技術分享圖片
1  public class TestIntercept : ITestIntercept
2 {
3     public string Test(string p)
4     {
5         throw new Exception("異常了"); //演示拋出異常,攔截器是否能捕捉到異常信息
6             //return p;
7     }
8 }
View Code

基本的異常攔截準備工作已經完畢,我們看看如何使用攔截器對方法進行攔截。

技術分享圖片
 1 using Castle.DynamicProxy; //必須的
 2 class Program
 3     {
 4         static void Main(string[] args)
 5         {
 6             MyIntercept myIntercept = new MyIntercept();//實例化攔截器
 7             ProxyGenerator proxy = new ProxyGenerator(); //實例化代理
 8             ITestIntercept intercept = proxy.CreateInterfaceProxyWithTarget<ITestIntercept>(new TestIntercept(),myIntercept);
 9             intercept.Test("william");
10             Console.ReadLine();
11         }
12     }
View Code

好了,一個簡單的方法攔截demo完成,他可以應用到很多場景,比如:權限驗證,異常統計等等。

遺留問題,有興趣的同學可以試試:

1.如果接口中有多個方法,攔截器會全部攔截嗎?

2.ProxyGenerator,我才用的是CreateInterfaceProxyWithTarget對接口和實現類進行mapping。是否還有其他的方式進行mapping工作,例如配置文件?

3.本次demo中采用的是實現接口的方式對方法進行攔截,如果不用接口,攔截器是否會起作用。因為我發現在ProxyGenerator中有個CreateClassProxyWithTarget()函數。大家可以試試。

.NET 簡易方法攔截器