.net core autofac asyncinterceptor 异步拦截器帮助包
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放入你的项目中.样例代码可点击这里查看
其中的核心代码是封装实现一个支持异步处理的Interceptor,让开发者仅需关心实现所拦截的方法,在执行前后该添加什么处理逻辑.
核心源码如下:
//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;
}
}
异步拦截器的执行流程如下:
在所拦截的方法执行前,首先执行BeforeProceed,方法执行后,如果为同步方法,则后续执行AfterProceedSync
如果为异步方法,则await方法使其真正执行后,调用AfterProceedAsync.通过hasAsynResult可判断是否有返回值.
如果有返回值也可通过ProceedAsynResult读取或修改所拦截方法的最终返回值.

对于此问题的其他拦截器实现方法的代码样例,可参照代码:https://github.com/wswind/Learn-AOP/tree/master/AutofacAsyncInterceptor-More
.net core autofac asyncinterceptor 异步拦截器帮助包的更多相关文章
- .net core autofac asyncinterceptor 异步拦截器开发
autofac使用拦截器实现AOP,是基于Castle.Core的.然而Castle.Core并未提供原生异步支持.所以需要使用帮助类实现,这在autofac官方文档的已知问题中有详细说明: http ...
- ASP.NET Core搭建多层网站架构【9.2-使用Castle.Core实现动态代理拦截器】
2020/01/31, ASP.NET Core 3.1, VS2019, Autofac.Extras.DynamicProxy 4.5.0, Castle.Core.AsyncIntercepto ...
- ASP.NET Core 3.0 gRPC 拦截器
目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 拦截器 一. 前言 前面两篇文章给大家介绍了使用g ...
- 014-Spring Boot web【三】拦截器HandlerInterceptor、异常处理页面,全局异常处理ControllerAdvice
一.拦截器HandlerInterceptor 1.1.HandlerInterceptor接口说明 preHandle,congtroller执行前,如果返回false请求终端 postHandle ...
- SpringMVC之八:基于SpringMVC拦截器和注解实现controller中访问权限控制
SpringMVC的拦截器HandlerInterceptorAdapter对应提供了三个preHandle,postHandle,afterCompletion方法. preHandle在业务处理器 ...
- 源码解析Grpc拦截器(C#版本)
前言 其实Grpc拦截器是我以前研究过,但是我看网上相关C#版本的源码解析相对少一点,所以笔者借这篇文章给大家分享下Grpc拦截器的实现,废话不多说,直接开讲(Grpc的源码看着很方便,包自动都能还原 ...
- struts2:拦截器
拦截器(Interceptor)是Struts 2的核心组件,Struts 2框架的大部分功能都是通过拦截器来完成的,例如数据校验,国际化,文件上传和下载等.为了实现这些功能,Struts 2框架提供 ...
- Web系统Login拦截器
所需要导入的包类:import org.springframework.web.servlet.HandleInterceptor;(拦截器要继承该类) public class loginInter ...
- 第十篇——Struts2的拦截器栈
拦截器栈: 从结构上看:拦截器栈相当于多个拦截器的组合: 从功能上看:拦截器栈也是拦截器. 默认拦截器栈: 在struts-core.jar包中的struts-default.xml中自定义了一个de ...
随机推荐
- h5页面在浏览器上好好的,到手机上熄火了又看不到报错信息怎么办?
背景 最近小编接了一个新需求,用h5开发页面,通过webview嵌入原生APP中,自己在浏览器上开发爽歪歪,什么信息都能看到,可是一嵌入原生app中,瞬间就熄火了,啥也看不到了,不知道为什么,反正就是 ...
- nacos快速安装
一 什么是 Nacos 服务注册中心和配置中心. 二 使用 下载和启动 使用有两种方式 1.自己下载源码编译 2.下载编译好的压缩包 我比较懒选择了第二种方式. 最新稳定版本 下载地址:https:/ ...
- 1.5Hadoop的启动
- Vue+Java+Base64实现条码解析
前端部分(Vue + Vant) 引入Vant.使用Vant中的Uploader组件上传文件(支持手机拍照) import Vue from 'vue'; import { Uploader } fr ...
- 《InnoDB存储引擎》笔记
第1章 Mysql体系结构和存储引擎 1.1 定义数据库和实例 数据库:database,物理的操作系统文件或其他形式文件类型的集合.当使用NDB存储引擎时,数据库文件可能是存放在内存中而不是磁盘之上 ...
- Metasploit之后渗透攻击(信息收集、权限提升)
利用永恒之蓝漏洞入侵Windows7 流程参考https://www.jianshu.com/p/03a1c13f963a,实在是太棒啦!!! 目标主机为win7(IP:192.168.1.102): ...
- 接口鉴权,提供给第三方调用的接口,进行sign签名
//场景:公司要跟第三方公司合作,提供接口给对方对接,这样需要对接口进行授权,不然任何人都可以调我们公司的接口,会导致安全隐患: 思路: 在每个接口请求参数都带上ApiKey 和sign签名: 我们在 ...
- SQL Server 子查询遇到的坑
这两天改 Bug 时使用 Sql Server 的子查询遇到了一些问题,特此记录一下,之前用 MySQL 比较多,按照 MySQL 的语法其实是没有问题的. 以下面这张表为例: 执行以下 SQL: s ...
- puts()和gets()函数
puts()和gets()函数 1. puts()函数 puts()函数用来向标准输出设备(屏幕)写字符串并换行, 其调用格式为: puts(s); 其中s为字符串变量(字符串数组名或字符串指针). ...
- 磁盘 IOPS(每秒读写次数) 的计算方法
一.磁盘 I/O 的概念 I/O 的概念,从字义来理解就是输入输出.操作系统从上层到底层,各个层次之间均存在 I/O.比如,CPU 有 I/O,内存有 I/O, VMM 有 I/O, 底层磁盘上也有 ...