Autofac 是個IOC容器  不懂IOC 參考 我之前寫
的IOC(控制反轉),DI(依賴注入) 深入淺出~~
小弟之前有一個開源框架【C#】 AOP輕型框架 AwesomeProxy.Net 介紹使用 裡面簡單介紹 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 許可協議。轉載請註明出處!
