Autofac 是個IOC容器 不懂IOC 參考 我之前寫
的IOC(控制反轉),DI(依賴注入) 深入淺出~~
小弟之前有一個開源框架 裡面簡單介紹 AOP核心概念和如何實作!
Autofac 有寫一個 Autofac.Extras.DynamicProxy 把AOP和IOC容器融合的框架
在Autofac使用AOP 需要實現下面幾個步驟
本次範例我們從資料庫中撈取時間資料出來,並使用Thread.Sleep(5000)
作出延遲,判斷時間是否前後一致。
第一步(定義攔截器):
我們撰寫一個快取的攔截器繼承IInterceptor
介面,並實現Intercep
方法
其中 IInvocation
參數有許多有用的資料
- Arguments:傳入方法中的參數
- InvocationTarget :被代理物件
- MethodInvocationTarget:被代理物件的呼叫方法資訊
- Proxy:代理物件
- Method:代理的呼叫方法資訊
- ReturnValue:呼叫方法的回傳值
這幾個欄位是我們比較常用的資訊
public class TimeInterceptor : IInterceptor
{
private ITimeService _timeService;
public TimeInterceptor(ITimeService s)
{
_timeService = s;
}
public void Intercept(IInvocation invocation)
{
var time = CallContext.GetData("time")?.ToString();
if (time == null)
{
//如果沒有快取 執行呼叫Service
invocation.Proceed();
CallContext.SetData("time", invocation.ReturnValue);
}
else
{
//如果有快取直接取值
invocation.ReturnValue = time;
}
}
}
他使用到 TimeService
模擬從資料庫中撈取資料出來
public interface ITimeService
{
string GetTime();
}
public class TimeService : ITimeService
{
public string GetTime()
{
return DateTime.Now.ToString("MM/dd/yyyy hh:mm:ss");
}
}
第二步(標記攔截器):
使用Intercept
標籤並帶入要攔截類別型態.
[Intercept(typeof(TimeInterceptor))]
public class Person : IPerson
{
public string SaySomething()
{
return DateTime.Now.ToLongTimeString();
}
}
public interface IPerson
{
string SaySomething();
}
第三步(註冊攔截器到容器中):
這邊有兩個小細節
- 如果是註冊介面使用
EnableInterfaceInterceptors
,註冊一般類別使用EnableClassInterceptors
- 註冊攔截器入容器
因為這個範例使用所以我們要呼叫
EnableInterfaceInterceptors
var builder = new ContainerBuilder();
builder.RegisterType<TimeInterceptor>(); //註冊攔截器
builder.RegisterType<Person>()
.As<IPerson>()
.EnableInterfaceInterceptors();
//註冊時間Service
builder.RegisterType<TimeService>().As<ITimeService>();
return builder.Build();
原始碼連結
小結
Autofac + DynamicProxy 有一個很大優勢,是可以把要注入的抽象動作一起注入攔截器中
例如本次範例我們將ITimeService
使用建構子注入法,注入至TimeInterceptor
攔截器中
讓系統和寫法擁有更多更多的彈性
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/autofac-aop/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!