AOP 框架基礎
要求懂的知識:AOP、Filter、反射(Attribute)。
如果直接使用 Polly,那么就會造成業務代碼中混雜大量的業務無關代碼。我們使用 AOP (如果不了解 AOP,請自行參考網上資料)的方式封裝一個簡單的框架,模仿 Spring cloud 中的 Hystrix。
需要先引入一個支持.Net Core 的 AOP,我們用.Net Core 下的 AOP 框架是AspectCore(國產,動態織入),其他要不就是不支持.Net Core,要不就是不支持對異步方法進行攔截 MVC Filter。
GitHub:https://github.com/dotnetcore/AspectCore-Framework
Install-Package AspectCore.Core -Version 0.5.0
這里只介紹和我們相關的用法:
1、編寫攔截器CustomInterceptorAttribute 一般繼承自AbstractInterceptorAttribute
public class CustomInterceptorAttribute:AbstractInterceptorAttribute
{
//每個被攔截的方法中執行
public async override Task Invoke(AspectContext context, AspectDelegate next)
{
try
{
Console.WriteLine("執行之前");
await next(context);//執行被攔截的方法
}
catch (Exception)
{
Console.WriteLine("被攔截的方法出現異常");
throw;
}
finally
{
Console.WriteLine("執行之后");
}
}
}
2、編寫需要被代理攔截的類
在要被攔截的方法上標注CustomInterceptorAttribute 。類需要是public類,方法如果需要攔截就是虛方法,支持異步方法,因為動態代理是動態生成被代理的類的動態子類實現的。
public class Person
{
[CustomInterceptor]
public virtual void Say(string msg)
{
Console.WriteLine("service calling..."+msg);
}
}
3、通過AspectCore創建代理對象
ProxyGeneratorBuilder proxyGeneratorBuilder = new ProxyGeneratorBuilder();
using (IProxyGenerator proxyGenerator = proxyGeneratorBuilder.Build())
{
Person p = proxyGenerator.CreateClassProxy<Person>();
p.Say("rupeng.com");
}
Console.ReadKey();
注意p指向的對象是AspectCore生成的Person的動態子類的對象,直接new Person是無法被攔截的。
研究AOP細節
攔截器中Invoke方法下的參數AspectContext的屬性的含義:
Implementation 實際動態創建的Person子類的對象。
ImplementationMethod就是Person子類的Say方法
Parameters 方法的參數值。
Proxy==Implementation:當前場景下
ProxyMethod==ImplementationMethod:當前場景下
ReturnValue返回值
ServiceMethod是Person的Say方法

