(八)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

相關文章