• (八)React Ant Design Pro + .Net5 WebApi:后端环境搭建Aop


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

  • 相关阅读:
    记录一次Centos磁盘空间占满的解决办法(转)
    Linux的php-fpm优化心得-php-fpm进程占用内存大和不释放内存问题(转)
    解决find命令报错: paths must precede expression(转)
    saltstack 使用salt ‘*’ test.ping 报错Minion did not return(转)
    Linux删除软链接
    循环队列
    正益无线首页jQuery焦点图
    基于jQuery点击缩略图右侧滑出大图特效
    基于jQuery垂直多级导航菜单代码
    带网上开户表单jQuery焦点图
  • 原文地址:https://www.cnblogs.com/WinterSir/p/15939848.html
Copyright © 2020-2023  润新知