在 CAP 中使用 AOP ( Castle.DynamicProxy )
- 2021 年 1 月 5 日
- 筆記
- .NET Core, Asp.Net Core, CAP, Castle
簡介
本篇文章主要介紹如何在 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 來執行,所以無需擔心資源釋放問題。
3、創建 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}");
}
}
4、在 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 的文檔地址:
//github.com/castleproject/Core/blob/master/docs/dynamicproxy.md
CAP 的 Github 地址:
本文地址://www.cnblogs.com/savorboard/p/cap-castle.html
作者部落格:Savorboard
本文原創授權為:署名 – 非商業性使用 – 禁止演繹,協議普通文本 | 協議法律文本