(八)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
(八)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Aop的更多相关文章
- (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建
		首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ... 
- (三)React Ant Design Pro + .Net5 WebApi:后端环境搭建
		一. 简介 1. 平常用的core webapi 3.1,恰逢.Net5.0正式版发布了,直接开整. 2. 先学习IdentityServer4 .Autofac.EF Core,集成到后台框架里. ... 
- (六)React Ant Design Pro + .Net5 WebApi:后端环境搭建-EF Core
		一. 简介 EFCore 是轻量化.可扩展.开源和跨平台版的常用数据访问技术,走你(官方文档) 二. 使用 1.安装数据库驱动包.PMC 工具包 不同的数据库有不同的包,参考,我用 PostgreSQ ... 
- (十)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(二)授权模式
		一.前言 先交代一下整个Demo项目结构: 一个认证服务(端口5000)IdentityServer4.Authentication 五个授权模式(两个控制台程序,三个MVC项目端口5001)文件夹G ... 
- (五)React Ant Design Pro + .Net5 WebApi:后端环境搭建-Autofac注入+ 泛型仓储
		一. 简介 Autofac与.Net Core自带DI的区别,大佬级的文章数不胜数.我只是根据实际应用简单介绍(非常简单的那种) 1.批量注入,自带DI需要自己写循环反射注入,Autofac现成方法, ... 
- (七)React Ant Design Pro + .Net5 WebApi:后端环境搭建-日志、异常处理
		一.日志 日志具有帮助开发者快速的定位问题,记录各种信息,配合其他分析框架使用等等功能,收集日志的各类框架如:Log4net.NLog.Exceptionless.Serilog等等,百度或园子里介绍 ... 
- (九)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4-简单配置
		一.简介 IdentityServer4 是用于 ASP.NET Core 的 OpenID Connect 和 OAuth 2.0 框架,通过中间件的方式集成.JWT(json web token) ... 
- (十一)React Ant Design Pro + .Net5 WebApi:后端环境搭建-IdentityServer4(三)持久化
		一.前言 IdentityServer配合EFCore持久化,框架已经为我们准备了两个上下文: ConfigurationDbContext:配置数据(资源.客户端.身份等) PersistedGra ... 
- (一)React Ant Design Pro + .Net5 WebApi:先搞定服务器,顺手装个Nginx
		腾讯云搞定服务器,具体过程就不赘述了,文档都有,咨询客服或者自行百度,体验一下过程. 一. 服务器 1. 云服务器 cvm 1核2G centos8.0 2. 域名注册 www.homejok.com ... 
随机推荐
- Nodejs ORM框架Sequelize(模型,关联表,事务,循环,及常见问题)
			1.建立连接 const Sequelize = require('sequelize'); const sequelize = new Sequelize('database', 'username ... 
- Web集群调度器-Haproxy
			Web集群调度器-Haproxy 目录 Web集群调度器-Haproxy 一.Web集群调度器 1.常用的Web集群调度器 2. Haproxy应用分析 3. Haproxy的主要特性 4. 常用集群 ... 
- Jenkins敏捷开发 自动化构建工具
			一.序言 Jenkins 是一款自动化构建工具,能够基于 Maven 构建后端 Java 项目,也能够基于 nodejs 构建前端 vue 项目,并且有可视化 web 界面. 所谓自动化构建是按照一定 ... 
- 6、架构--Nginx虚拟主机(基于多ip、端口、域名方式)、日志配置、Nginx模块(访问控制模块、状态监控模块、访问链接控制模块)
			笔记 1.晨考 2.昨日问题 3.今日内容 1.Nginx虚拟主机 - 基于多IP的方式 - 基于多端口的方式 - 基于多域名的方式 2.日志配置 Nginx有非常灵活的日志记录模式,每个级别的配置可 ... 
- 天啦,从Mongo到ClickHouse我到底经历了什么?
			前言: 在实现前端监控系统的最初,使用了 Mongo 作为日志数据存储库.文档型存储,在日志字段扩展和收缩上都能非常方便.天生的 JSON 格式和 NodeJs 配合也非常贴合.就这样度过了几个月的蜜 ... 
- SIMD编码/解码
			在看SEAL库和HElib库中经常在编码中碰到打包(batch)技术,另外还提到了SIMD编码技术,有点困惑,编码.打包.SIMD到底有什么关系? 编码 在CKKS方案中,因为明文空间在复数域上,简单 ... 
- 上架打包错误:error itms-90086
			这是一个很纠结的错误 大家第一反应肯定是 赶紧去看看 位数是否设置 然后发现没有问题 就开始懵逼了 (比如我) 然而无意看到了一个人写的简书 这个人在 Overflow 找到了一个答案 比如你选择 ... 
- PostgreSQL VACUUM 之深入浅出 (一)
			前言 VACUUM 是 PostgreSQL MVCC (Multiversion concurrency control) 实现的核心机制之一,是 PostgreSQL 正常运行的重要保证.本文将通 ... 
- [LeetCode]1313. 解压缩编码列表
			给你一个以行程长度编码压缩的整数列表 nums . 考虑每对相邻的两个元素 [freq, val] = [nums[2i], nums[2i+1]] (其中 i >= 0 ),每一对都表示解压后 ... 
- Python中模块、类、函数、实例调用案例
			19 a = '我是模块中的变量a' 20 21 def hi(): 22 a = '我是函数里的变量a' 23 print('函数"hi"已经运行!') 24 25 class ... 
