一、Castle
使用這個框架呢,首先是需要安裝NuGet包。
先建立一個控制台項目,然后在NuGet中搜索Castle.Windsor,不出意外的話應該能找到如下的包
然后安裝,會自動的安裝包Castle.Core
創建一個類CastleWindsor,實現接口IInterceptor,這個接口呢就在Castle.Core.dll中了
class CastleWindsor : IInterceptor { public void Intercept(IInvocation invocation) { PreProceed(invocation); Console.WriteLine("ffff"); invocation.Proceed(); PostProceed(invocation); } public void PreProceed(IInvocation invocation) { Console.WriteLine("方法執行前"); } public void PostProceed(IInvocation invocation) { Console.WriteLine("方法執行后"); } }
類中的Intercept函數來自於接口IInterceptor。而函數IInterceptor和PostProceed並不是必須的,可以沒有這兩個函數,主要還是看Intercept函數中的invocation.Proceed();這一句。在這一句之前添加的代碼肯定先於修飾的函數執行,在這之后的代碼,晚於
修飾的函數執行。
然后定義服務端,就是完成業務功能的代碼段。
public interface IUserProcessor { void RegUser(string txt); void WriteMessage(string msg); } public class UserProcessor : IUserProcessor { public virtual void RegUser(string txt) { Console.WriteLine("用戶已注冊。Name:{0}", txt); } public virtual void WriteMessage(string msg) { Console.WriteLine(msg); } }
假設的是這個接口和類就是為了完成業務功能的地方。
然后創建客戶端來調用服務端:
class CoreBusiness
{
public void Work_5()
{ try { Castle.DynamicProxy.ProxyGenerator generator = new Castle.DynamicProxy.ProxyGenerator(); CastleWindsor interceptor = new CastleWindsor(); IUserProcessor userprocessor = generator.CreateClassProxy<UserProcessor>(interceptor); userprocessor.WriteMessage("555555555555"); userprocessor.RegUser("123123123123"); } catch (Exception ex) { throw ex; } }
}
注意看這個客戶端的代碼,這里有一個UserProcessor的對象userprocessor,但是卻沒有通過new關鍵字來創建,而是通過ProxyGenerator的CreateClassProxy函數來創建,從而將CastleWindsor類和UserProcessor類聯系起來了。
在main函數中調用Work_5,執行結果:
從執行結果中可以看出來,每次調用服務端的函數,都會執行Intercept函數。
這個框架來實現AOP的話,如果是項目開發中就應用了這個框架還好,否則在開發完成后才來引入這個框架,那么勢必要對原來的代碼進行大量的修改。這一點上還不如篩選器和postsharp框架。
當然這個框架也可以在函數執行前獲取函數的參數值,在函數執行后,能獲取函數的返回值。要注意的是,不能獲取到函數的參數名。
通過以下方式來獲取參數值和返回值
invocation.Method.Name:函數名
invocation.Arguments:參數值的數組。invocation.Arguments的類型是object[]
invocation.ReturnValue:函數返回值,注意這個必須是在invocation.Proceed()執行之后且函數有返回值的情況下才有值。類型是object
看看Intercept函數的參數類型。注意標紅線的地方。ReturnValue不是只讀的,那就是說可以在函數執行完成后,去修改函數的返回值。SetArgumentValue表示可以在函數執行前,去修改函數的參數。