在 CAP 中使用 AOP ( Castle.DynamicProxy )

簡介

本篇文章主要介紹如何在 CAP 中集成使用 Castle.DynamicProxy,Castle DynamicProxy 是一個用於在運行時動態生成輕量級.NET代理的庫。代理對象允許在不修改類代碼的情況下截取對對象成員的調用。可以代理類和接口,但是隻能攔截虛擬成員。

爲什麼需要使用 AOP

Castle.DynamicProxy 爲 AOP 的一種實現方式,AOP 爲 Aspect Oriented Programming 的縮寫,意爲:面向切面編程,通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。

Castle.DynamicProxy 可以幫助你方便的創建代理對象,代理對象可以幫助構建靈活的應用程序體系結構,因爲它允許將功能透明地添加到代碼中,而無需對其進行修改。例如,可以代理一個類來添加日誌記錄或安全檢查,而無需使代碼知道已添加此功能。

下面可以看到如何在 CAP 中集成使用 Castle.DynamicProxy。

Getting Started

1、安裝 NuGet 包

在 集成了 CAP 的項目中安裝包,有關如何集成 CAP 的文檔請看這裏

注意,Castle.DynamicProxy 這個包已經被廢棄,請使用最新的 Castle.Core 包。

<PackageReference Include="Castle.Core" Version="4.4.1" />

2、創建一個 Castle 切面攔截器

可以在這裏 dynamicproxy.md 找到相關的文檔。

下面爲示例代碼,繼承 Castle 提供的 IInterceptor 接口即可:

[Serializable]
public class MyInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Before target call");
        try
        {
            invocation.Proceed();
        }
        catch (Exception)
        {
            Console.WriteLine("Target threw an exception!");
            throw;
        }
        finally
        {
            Console.WriteLine("After target call");
        }
    }
}

攔截器此處命名爲 MyInterceptor,你可以在其中處理你的業務邏輯,比如添加日誌或其他的一些行爲。

3、創建 IServiceCollection 的擴展類

IServiceCollection 創建擴展,方面後續調用。

using Castle.DynamicProxy;

public static class ServicesExtensions
{
    public static void AddProxiedSingleton<TImplementation>(this IServiceCollection services)
        where TImplementation : class
    {
        services.AddSingleton(serviceProvider =>
        {
            var proxyGenerator = serviceProvider.GetRequiredService<ProxyGenerator>();
            var interceptors = serviceProvider.GetServices<IInterceptor>().ToArray();
            return proxyGenerator.CreateClassProxy<TImplementation>(interceptors);
        });
    }
}

此處我創建了一個 Singleton 聲明週期的擴展方法,建議所有 CAP 的訂閱者都創建爲 Singleton 即可,因爲在 CAP 內部實際執行的時候也會創建一個 scope 來執行,所以無需擔心資源釋放問題。

4、創建 CAP 訂閱服務

創建一個 CAP 訂閱類,注意不能放在 Controller 中了。

注意:方法需要爲虛方法 virtual,才能被 Castle 重寫,別搞忘了加!!!

public class CapSubscribeService: ICapSubscribe
{
    [CapSubscribe("sample.rabbitmq.mysql")]
    public virtual void Subscriber(DateTime p)
    {
        Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
    }
}

5、在 Startup 中集成

public void ConfigureServices(IServiceCollection services)
{
    // 添加 Castle 的代理生成器
    services.AddSingleton(new ProxyGenerator());
    
    // 添加第2步的自定義的攔截類,聲明週期爲
    services.AddSingleton<IInterceptor, MyInterceptor>();
    
    // 此處爲上面的擴展方法, 添加 CAP 訂閱 Service
    services.AddProxiedSingleton<CapSubscribeService>();
    
    services.AddCap(x =>
    {
        x.UseMySql("");
        x.UseRabbitMQ("");
        x.UseDashboard();
    });
    
    // ...
}

以上就完成了所有的集成工作,可以開始進行測試了,有問題歡迎到 Github issue 反饋。

注意: CAP 需要使用 5.0 + 版本,目前只有 preview 版本。

總結

以上就是如何在 CAP 中使用 Castle 進行代理,如果你覺得有用,歡迎右下角點贊。

參考地址:

Castle DynamicProxy 的文檔地址:

https://github.com/castleproject/Core/blob/master/docs/dynamicproxy.md

CAP 的 Github 地址:

https://github.com/dotnetcore/cap


本文地址:http://www.cnblogs.com/savorboard/p/cap-castle.html
作者博客:Savorboard
本文原創授權爲:署名 - 非商業性使用 - 禁止演繹,協議普通文本 | 協議法律文本

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章