Castle~動態代理實現對方法的攔截


昨天寫了關於使用Castle.Windsor來實現IOC功能,今天需要寫一下使用Castle實現對方法的攔截,這實事上是.net平台實現AOP編程的基礎,當你可以對方法進行攔截時,你就可以動態地干很多事,如在方法執行前做權限驗證,執行后到日志記錄,異常處理等等,怎么樣看到這里,胃口來了吧,呵呵,對於技術痴迷者來說,這是正常的,好了,說干就干!

前言:我們在開發項目時,你的項目可能已經上線運營了,內部的代碼如果修改風險是很大的,這當然也不符合OCP了,你這前的代碼在運營過程中已經將BUG修改完成,運行很穩定,但這時,你的BOSS要求你在方法操作之前做一下驗證,這時,你怎么辦?

方法1:改原來的方法,風險呀,原則呀!

這當然不是我們推薦的方法,它的風險性是可想而知的,你修改自己的代碼還好,如果是修改別人寫的代碼,那麻煩就更大了,呵呵。

方法2:使用動態代理Castle,dynamic proxy在java中已經不是新鮮事物了,但在.net中還是比較少見的技術,實現的組件也不多

這雖然有些復雜度,但聽起來不錯,值得嘗試,事實上在小微的orchard項目中早已經開始使用它了,功能模塊的動態插拔確實需要這樣一種技術。

實現:

一個用戶業務類,它在運行過程中很穩定,代碼如下:

 1    public interface IUserBLL
 2     {
 3         void GetUser(string pre);
 4     }
 5 
 6     public class UserBLL : IUserBLL
 7     {
 8         public virtual void GetUser(string pre)
 9         {
10             Console.WriteLine(pre + ",GSpring");
11         }
12 
13     }

但在項目二期工程中,BOSS要求在這個GetUser 方法執行之前,要驗證一個用戶的權限,如果滿足要求才能被用戶列表,這時,我們有了castle

就可以不修改上面的代碼了(注意要被代理的方法必須是virtual虛方法,因為它會被代理類重寫(override)的,呵呵 )。

為GetUser方法加權限了,代碼如下:

 1  /// <summary>
 2     /// Summary description for DaoProxy.
 3     /// </summary>
 4     public class UserRoleInterceptorProxy : IInterceptor
 5     {
 6         string _arg;
 7         public UserRoleInterceptorProxy(string arg)
 8         {
 9             _arg = arg;
10         }
11         public void Intercept(IInvocation invocation)
12         {
13             //這里可以進行數據庫連接、日志、異常處理、權限判斷等共通操作
14             //Console.WriteLine("{0}方法調用之前", _arg);
15             //invocation.Proceed();//處理被代理的部分
16             //Console.WriteLine("{0}方法調用之后", _arg);
17             if (_arg == "zzl") //這里可以寫你的驗證邏輯
18                 invocation.Proceed();//處理被代理的部分
19             else
20                 Console.WriteLine("{0}您沒有操作的權限", _arg);
21 
22         }
23 
24     }

在使用GetUser方法的地方,要被重寫為:

1        #region Dynamic Proxy
2             var proxyGenerator = new ProxyGenerator();
3             var handler = new UserRoleInterceptorProxy[] { new UserRoleInterceptorProxy("zhz") };
4             IUserBLL iRole = proxyGenerator.CreateClassProxy<UserBLL>(handler);
5             iRole.GetUser("zzl");
6           #endregion

程序運行的結果為:

恩,這個技術有點意思,我將會在后面的文章中對動態代碼進行一個封裝,讓大家調用起來更方便!

感謝閱讀!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM