(八)React Ant Design Pro + .Net5 WebApi:後端環境搭建-Aop
阿新 • • 發佈:2022-03-18
一、Aop
Aop 面向切面程式設計(Aspect Oriented Program),在專案中,很多地方都會用到Aop的概念,比如:過濾器(Filter),中介軟體(Middleware) 通常用來處理資料請求、切面快取、記錄日誌、異常捕獲等等。但是想在服務層中使用Aop,前面說的就不好使了,目的是減少程式碼入侵,降低解耦,又能實現業務需求,才是Aop意義所在。前面介紹使用了Autofac,在這還能發揮作用。
1、安裝
安裝Autofac.Extras.DynamicProxy,Autofac實現Aop用的是Castle.Core動態代理,Castle.Core可以單獨使用,跟Autofac配合起來更方便。Autofac.Extras.DynamicProxy依賴Autofac,所以有的文章是直接就裝了這個包,一個效果。
2、非同步處理
Castle.Core本身是不支援非同步的,所以參考封裝非同步Aop類 AsyncInterceptorBase 繼承 IInterceptor。
public abstract class AsyncInterceptorBase : IInterceptor { public AsyncInterceptorBase() { } public void Intercept(IInvocation invocation) { BeforeProceed(invocation); invocation.Proceed(); if (IsAsyncMethod(invocation.MethodInvocationTarget)) { InterceptAsync((dynamic)invocation.ReturnValue, invocation); } else { AfterProceedSync(invocation); } } private bool CheckMethodReturnTypeIsTaskType(MethodInfo method) { var methodReturnType = method.ReturnType; if (methodReturnType.IsGenericType) { if (methodReturnType.GetGenericTypeDefinition() == typeof(Task<>) || methodReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>)) return true; } else { if (methodReturnType == typeof(Task) || methodReturnType == typeof(ValueTask)) return true; } return false; } private bool IsAsyncMethod(MethodInfo method) { bool isDefAsync = Attribute.IsDefined(method, typeof(AsyncStateMachineAttribute), false); bool isTaskType = CheckMethodReturnTypeIsTaskType(method); bool isAsync = isDefAsync && isTaskType; return isAsync; } private async Task InterceptAsync(Task task, IInvocation invocation) { await task.ConfigureAwait(false); AfterProceedAsync(invocation, false); } private async Task<TResult> InterceptAsync<TResult>(Task<TResult> task, IInvocation invocation) { TResult ProceedAsyncResult = await task.ConfigureAwait(false); invocation.ReturnValue = ProceedAsyncResult; AfterProceedAsync(invocation, true); return ProceedAsyncResult; } private async ValueTask InterceptAsync(ValueTask task, IInvocation invocation) { await task.ConfigureAwait(false); AfterProceedAsync(invocation, false); } private async ValueTask<TResult> InterceptAsync<TResult>(ValueTask<TResult> task, IInvocation invocation) { TResult ProceedAsyncResult = await task.ConfigureAwait(false); invocation.ReturnValue = ProceedAsyncResult; AfterProceedAsync(invocation, true); return ProceedAsyncResult; } protected virtual void BeforeProceed(IInvocation invocation) { } protected virtual void AfterProceedSync(IInvocation invocation) { } protected virtual void AfterProceedAsync(IInvocation invocation, bool hasAsynResult) { } }
新建一個服務切面類 ServiceAop 繼承 AsyncInterceptorBase
public class ServiceAop : AsyncInterceptorBase { private readonly ILogger<ServiceAop> _logger; public ServiceAop(ILogger<ServiceAop> logger) { _logger = logger; } protected override void BeforeProceed(IInvocation invocation) { _logger.LogInformation($"ServiceAop呼叫方法:{invocation.Method.Name},引數:{JsonConvert.SerializeObject(invocation.Arguments) }"); } protected override void AfterProceedSync(IInvocation invocation) { _logger.LogInformation($"ServiceAop同步返回結果:{JsonConvert.SerializeObject(invocation.ReturnValue)}"); } protected override void AfterProceedAsync(IInvocation invocation, bool hasAsynResult) { _logger.LogInformation($"ServiceAop非同步返回結果:{JsonConvert.SerializeObject(invocation.ReturnValue)}"); } }
兩個類放在了新建的Aop資料夾裡,通過Autofac注入進行使用,修改 Startup.cs 程式碼如圖:(不太明白的請看:(五)Autofac)
3、使用效果
二、前人栽樹,後人乘涼
https://blog.csdn.net/q932104843/article/details/97611912
https://www.cnblogs.com/wswind/p/13863104.html