.net core autofac asyncinterceptor 异步拦截器帮助包

背景

autofac使用拦截器实现AOP,是基于Castle.Core的.然而Castle.Core并未提供原生异步支持.所以需要使用帮助类实现,这在autofac官方文档的已知问题中有详细说明
对于该问题的讨论,最早出现于stackoverflow
James Skimming基于其中的一个答案,研发了一个帮助包即: Castle.Core.AsyncInterceptor
我之前也一直使用的是该方案,不过thepirat000随后提出了一个使用dynamic的更加简化的实现方法
我对该方法进行了一些封装,实现了一个帮助包,大家可以尝试一下,项目地址位于:https://github.com/wswind/lightwind

使用

使用时,你可以通过nuget安装Lightwind.Asyncinterceptor也可以直接拷贝AsyncInterceptorBase.cs放入你的项目中.样例代码可点击这里查看
其核心代码是封装实现一个支持异步处理的Interceptor父类,让开发者能够继承实现自己的拦截器。开发时,仅需关注所拦截的方法,在执行前后该添加什么处理逻辑.
异步拦截器的执行流程如下:
在所拦截的方法执行前,首先执行BeforeProceed,方法执行后,如果为同步方法,则后续执行AfterProceedSync
如果为异步方法,则await所拦截的方法使其真正执行后,调用AfterProceedAsync进行异步方法的后续处理。
对于异步执行且有返回值的情况,可通过hasAsynResult参数判断是否有返回值,通过ProceedAsynResult属性读取或修改所拦截方法的最终返回值.
代码的运行流程图如下:

AsyncInterceptorBase.cs核心实现如下:

public abstract class AsyncInterceptorBase : IInterceptor
{
    public AsyncInterceptorBase()
    { 
    }
    
    public void Intercept(IInvocation invocation)
    {
        BeforeProceed(invocation);
        invocation.Proceed();
        if (IsAsyncMethod(invocation.MethodInvocationTarget))
        {
            invocation.ReturnValue = InterceptAsync((dynamic)invocation.ReturnValue, invocation);
        }
        else
        {
            AfterProceedSync(invocation);
        }
    }

    //didn't support ValueTask yet
    protected virtual bool IsAsyncMethod(MethodInfo method)
    {
        var attr = method.GetCustomAttributes<AsyncStateMachineAttribute>(false);
        bool isAsync = (attr != null) && typeof(Task).IsAssignableFrom(method.ReturnType);
        return isAsync;
    }

    private async Task InterceptAsync(Task task, IInvocation invocation)
    {
        await task.ConfigureAwait(false);
        await AfterProceedAsync(invocation, false);
    }

    protected object ProceedAsynResult { get; set; }

    private async Task<TResult> InterceptAsync<TResult>(Task<TResult> task, IInvocation invocation)
    {
        TResult result = await task.ConfigureAwait(false);
        ProceedAsynResult = result;
        await AfterProceedAsync(invocation,true);
        return (TResult)ProceedAsynResult;
    }

    protected virtual void BeforeProceed(IInvocation invocation) {}

    protected virtual void AfterProceedSync(IInvocation invocation) {}

    protected virtual Task AfterProceedAsync(IInvocation invocation,bool hasAsynResult)
    {
        return Task.CompletedTask;
    }
} 

对于异步拦截器的其他实现方法,,可参考此代码样例

原文地址:https://www.cnblogs.com/wswind/p/autofac-asyncinterceptor.html