🚫 Ad Blocker Detected

Please disable your AD blocker to continue using this site. Ads help us keep the content free! please press keyboard F5 to refresh page after disabled AD blocker

請關閉廣告攔截器以繼續使用本網站。廣告有助於我們保證內容免費。謝謝! 關閉後請按 F5 刷新頁面

0%

Autofac + Interceptors(AOP) 動態代理

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();
}

第三步(註冊攔截器到容器中):

這邊有兩個小細節

  1. 如果是註冊介面使用EnableInterfaceInterceptors,註冊一般類別使用EnableClassInterceptors
  2. 註冊攔截器入容器

因為這個範例使用``所以我們要呼叫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 許可協議。轉載請註明出處!

如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^