【ASP.NET Core 3.1_參考中介軟體原始碼實現自定義AOP】
阿新 • • 發佈:2020-11-13
一、參考中介軟體原始碼實現自定義AOP
場景:在真實執行邏輯學習這個方法包一層層(學習前吃點東西、上個廁所),模擬中介軟體,一層層穿過
思路:物件構造完,加1個動態代理,基於Castle、組裝委託,來個AOP擴充套件,像一個俄羅斯套娃
二、AOP擴充套件方法--ContainerAOPExtensions.cs 2.1、Nuget引入Castle.Core.dll 2.2、實現擴充套件方法,目的把服務包一層代理
二、AOP擴充套件方法--ContainerAOPExtensions.cs 2.1、Nuget引入Castle.Core.dll 2.2、實現擴充套件方法,目的把服務包一層代理
/// <summary>
/// 自定義AOP擴充套件
/// </summary>
public static class ContainerAOPExtensions
{
/// <summary>
///
/// </summary>
/// <param name="t">物件</param>
/// <param name="interfaceType">介面型別</param>
/// <returns></returns>
public static object AOP(this object t, Type interfaceType)
{
ProxyGenerator generator = new ProxyGenerator();
ProxyInterceptor interceptor = new ProxyInterceptor();
t = generator.CreateInterfaceProxyWithTarget(interfaceType, t, interceptor);
return t;
}
}
三、自定義攔截屬性
3.1、基類
public abstract class BaseInterceptorAttribute : Attribute
{
public abstract Action Do(IInvocation invocation, Action action);
}
3.2、吃點東西攔截屬性/// <summary>
/// 學習前吃點東西
/// </summary>
public class EatInterceptorAttribute : BaseInterceptorAttribute
{
public override Action Do(IInvocation invocation, Action action)
{
return () =>
{
Console.WriteLine($"This is Eat1 {invocation.Method.Name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
//去執行真實邏輯
action.Invoke();
Console.WriteLine($"This is Eat2 {invocation.Method.Name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
};
}
}
3.3、上個廁所攔截屬性
/// <summary>
/// 學習前上個廁所
/// </summary>
public class GoToiletInterceptorAttribute : BaseInterceptorAttribute
{
public override Action Do(IInvocation invocation, Action action)
{
return () =>
{
Console.WriteLine($"This is GoToilet1 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
//去執行真實邏輯
action.Invoke();
Console.WriteLine($"This is GoToilet2 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
};
}
}
四、攔截器--ProxyInterceptor.cs
/// <summary>
/// 攔截器
/// </summary>
public class ProxyInterceptor : StandardInterceptor
{
/// <summary>
/// 呼叫前的攔截器
/// </summary>
/// <param name="invocation"></param>
protected override void PreProceed(IInvocation invocation)
{
Console.WriteLine($"呼叫前的攔截器 方法名是:{invocation.Method.Name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
}
/// <summary>
/// 攔截的方法返回時呼叫的攔截器
/// </summary>
/// <param name="invocation"></param>
protected override void PerformProceed(IInvocation invocation)
{
var method = invocation.Method;
//真實邏輯包成委託--Study()--對應學生服務裡的‘我要學習了’
Action action = () => base.PerformProceed(invocation);
if (method.IsDefined(typeof(BaseInterceptorAttribute), true))
{
foreach (var attribute in method.GetCustomAttributes<BaseInterceptorAttribute>().ToArray().Reverse())
{
//組裝、再組裝委託
action = attribute.Do(invocation, action);
}
}
//最後一次性執行委託
action.Invoke();
}
/// <summary>
/// 呼叫後的攔截器
/// </summary>
/// <param name="invocation"></param>
protected override void PostProceed(IInvocation invocation)
{
Console.WriteLine($"呼叫後的攔截器 方法名是:{invocation.Method.Name} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff")}");
}
}
五、學生介面、學生服務
5.1、IStudentService.cs
在介面上面加上自定義攔截屬性
/// <summary>
/// 學生介面
/// </summary>
public interface IStudentService
{
/// <summary>
/// 學習
/// </summary>
[EatInterceptor]
[GoToiletInterceptor]
public void Study();
}
5.2、StudentService.cs
Study()是真實邏輯/// <summary>
/// 學生服務
/// </summary>
public class StudentService : IStudentService
{
/// <summary>
/// 學習
/// </summary>
public void Study()
{
Console.WriteLine("我要學習了!");
}
}
六、上端呼叫
public class TestCustomAOPController : Controller
{
//學生服務介面
private IStudentService _iStudentService = null;
public TestCustomAOPController(IStudentService iStudentService)
{
_iStudentService = iStudentService;
}
public IActionResult Index()
{
Console.WriteLine("******************普通方法呼叫*********************");
_iStudentService.Study();
Console.WriteLine("*******************AOP擴充套件後********************");
_iStudentService = (IStudentService)_iStudentService.AOP(typeof(IStudentService));
_iStudentService.Study();
return View();
}
}
七、專案結構
八、執行效果
總結:把真實邏輯Study()方法先不執行,先包成委託傳入GoToilet,GoToilet裡面對委託組裝後返回一個委託,再次把返回的委託再次傳入Eat,Eat裡面對委託再次組裝後再返回一個委託,最後一次性執行委託
委託傳遞,組裝、再組裝、最後一次性執行委託,這其實就是我對ASP.NET Core Middleware中介軟體的理解
Castle、組裝委託,