autofac使用拦截器实现AOP,是基于Castle.Core的.然而Castle.Core并未提供原生异步支持.所以需要使用帮助类实现,这在autofac官方文档的已知问题中有详细说明:
https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html#asynchronous-method-interception
对于该问题的讨论,最早出现于stackoverflow:https://stackoverflow.com/questions/28099669/intercept-async-method-that-returns-generic-task-via-dynamicproxy
James Skimming基于其中的一个答案,研发了一个帮助包即: Castle.Core.AsyncInterceptor
我之前也一直使用的是该方案,不过thepirat000随后提出了一个使用dynamic的更加简化的实现方法:https://stackoverflow.com/a/39784559/7726468
我对其进行了一些封装,实现了一个新的帮助包,大家可以尝试一下,项目地址在:https://github.com/wswind/lightwind
使用时,你可以通过nuget安装Lightwind.Asyncinterceptor也可以直接拷贝AsyncInterceptorBase.cs放入你的项目中.
源码如下:

    //inspired by : https://stackoverflow.com/a/39784559/7726468
    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);
            }
        }

        protected bool IsAsyncMethod(MethodInfo method)
        {
            var attr = method.GetCustomAttributes<AsyncStateMachineAttribute>(true);
            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;
        }
    }

使用时,可自行定义拦截器继承AsyncInterceptorBase,并重载 BeforeProceed() , AfterProceedSync() , AfterProceedAsync() 三个方法.
调用顺序如下:

如需在拦截器中修改返回值,可修改ProceedAsynResult.
使用的样例代码请见:https://github.com/wswind/lightwind/tree/master/samples/AutofacAsyncInterceptor
对于此问题的其他拦截器实现方法的代码样例,可参照代码:https://github.com/wswind/Learn-AOP/tree/master/AutofacAsyncInterceptor-More

版权声明:本文为wswind原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/wswind/p/13863104.html