一、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