前言

最近项目要求在ABP框架中根据TenantId是否为空来配置是否禁用租户过滤器。ABP自身给我我们禁用租户过滤器的两种方法官方文档

https://aspnetboilerplate.com/Pages/Documents/Data-Filters

方法一:使用工作单元

using (_unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant))
{var people2 = _personRepository.GetAllList();
}

方法二:全局禁用过滤器

Configuration.UnitOfWork.OverrideFilter(AbpDataFilters.MayHaveTenant, false);

但是方法一要修改的地方很多,嫌麻烦;方法二只能全局在Configuration中配置,不能动态改变,也不合适。于是我查阅了APB AOP和拦截技术 ,另外查阅了ABP自身注册了拦截器——UnitOfWorkRegistrar,会默认为继承自IRepository或者是IApplicationService的两种类型添加UnitOfWork特性,于是便可以通过拦截方法去实现动态禁用过滤器。

具体实现

首先在Application 层新建一个TenantInterceptor 继承IInterceptor接口

public class TenantInterceptor : IInterceptor
{public ILogger Logger { get; set; }public TenantInterceptor(){Logger = NullLogger.Instance;}public void Intercept(IInvocation invocation){// 从invocation中拿到当前注册进来的工作单元,主要用于获取TenantIdType t = invocation.InvocationTarget.GetType();var unitOfWorkManager = (t.GetProperty("UnitOfWorkManager").GetValue(invocation.InvocationTarget)) as IUnitOfWorkManager;//根据TenantId是否禁用租户过滤器if (unitOfWorkManager.Current.GetTenantId().HasValue){invocation.Proceed(); // 执行方法体}else {// 禁用租户// PS:这里不可以使用 using        unitOfWorkManager.Current.DisableFilter(AbpDataFilters.MayHaveTenant, AbpDataFilters.MustHaveTenant);invocation.Proceed(); // 执行方法体}}
}

拦截器里的内容很简单,主要就是根据工作单元获取TenantId来动态禁用过滤器。因为这里没有需要返回的东西,也就不用分同步异步去拦截。

接下来就是为所需要禁用租户过滤器的类注册拦截器

public static class TenantInterceptorRegistrar
{public static void Initialize(IKernel kernel){kernel.ComponentRegistered += Kernel_ComponentRegistered;}private static void Kernel_ComponentRegistered(string key, IHandler handler){var implementationType = handler.ComponentModel.Implementation.GetTypeInfo();// 为实现了接口IRepository接口的所有类注册拦截器//if (typeof(IRepository).IsAssignableFrom(implementationType))//{//    handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(TenantInterceptor)));//}// 为指定类注册拦截器if (InternalAsyncHelper.DisableFilterTenantTypes.Any(a => a.IsAssignableFrom(implementationType))){handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(TenantInterceptor)));}}
}internal static class InternalAsyncHelper
{public static Type[] DisableFilterTenantTypes ={typeof(IRepository<Student,Guid>),typeof(IRepository<School,Guid>)};
}

TenantInterceptorRegistrarInitialize方法中,首先会注入整个ABP系统中唯一的IIocManager,然后就是订阅唯一的IocContainer这个容器的ComponentRegistered事件,在订阅事件中首先是获取当前触发此事件的类型信息,然后根据需求注册TenantInterceptor这个拦截器。

这里有一点需要注意,本来想为实现了IApplicationService接口的类注册拦截器,但是ASP.NET   Boilerplate使用动态方法拦截的功能有一些限制

  • 如果通过接口调用该方法,则可以将其用于任何公共方法(例如,通过接口使用的Application Services)。

  • 如果直接从类引用(例如ASP.NET  MVC或Web API控制器)中调用方法,则该方法应为虚拟方法。

  • 一种方法应该是虚拟的,如果它的保护。

也就是如果将服务作为客户端的Web API控制器公开,那么方法必须是虚方法(virtual) 附上官方Git issues

https://github.com/aspnetboilerplate/aspnetboilerplate/issues/3237

最后一步就是把拦截器在模块文件中初始化

public class ApplicationCoreModule : AbpModule
{public override void PreInitialize(){TenantInterceptorRegistrar.Initialize(IocManager.IocContainer.Kernel);}public override void Initialize(){}
}

这样就可以按着自己的需要在DisableFilterTenantTypes  中配置自己想配置的仓储了。

转载是一种动力 分享是一种美德

如果喜欢作者的文章,请关注【麦扣聊技术】订阅号以便第一时间获得最新内容。本文版权归作者和湖南心莱信息科技有限公司共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文作者:心莱科技CacoCode

文档官网:docs.xin-lai.com

QQ群:

编程交流群<85318032>

产品交流群<897857351>

ABP框架使用拦截器动态配置租户过滤器相关推荐

  1. vue跨域和拦截器的配置

    最近项目中需要使用vue框架.虽然vue在前端开发人员里也不算是什么新鲜的事儿了.只要是搞前端的都会一些vue的操作.我也不多说,直接进入正题.(这儿我以vue2.x为例) 安装什么的,我就不在这儿说 ...

  2. Struts2 拦截器的配置:

    Struts2 拦截器的配置: 第一步:在struts.xml文件中加入拦截器配置: 我们可以在配置拦截器的时候,自己定义一个拦截器栈来包含我们自己定义的拦截器(注意:一定要将 defaultStac ...

  3. Spring事务配置方式(一) 拦截器方式配置

    一.使用<tx:advice>和<aop:config>配置事务 <!-- 配置事务管理器 --><bean id="transactionMana ...

  4. vue2中使用axios,以及axios拦截器的配置

    目录 一.vue2项目中如何实现异步请求 1.axios:是一个基于Promise的网络请求库.既可以在node.js(服务器端)使用,也可以在浏览器端使用 2.vue中的使用方法 ​ (2)引用方法 ...

  5. 给axios的请求拦截器中配置token

    axios 1. 配置token 用户第一次登录系统时,服务器端会返回一个身份秘钥信息(token),表明当前用户有资格.权限访问服务器,客户端获取token之后,通过sessionStorage存储 ...

  6. CC00038.kafka——|Hadoopkafka.V23|——|kafka.v23|消费者拦截器参数配置|

    一.消费者拦截器参数配置:消费者参数配置补充 配置项 说明 bootstrap.servers 建立到Kafka集群的初始连接用到的host/port列表. 客户端会使用这里指定的所有的host/po ...

  7. Springmvc中的拦截器interceptor及与过滤器filter的区别

    一.Springmvc中的拦截器概述及与过滤器filter的区别 1).Springmvc中的拦截器interceptor用于对控制器controller进行预处理和后处理的技术; 2).可以定义拦截 ...

  8. Mybatis 通过拦截器动态修改SQL

    01 使用场景 当我们在多租户的项目中,编写SQL语句都要带上tenant字段,用于区分不同的租户只能操作自己的数据. 比如,像下面的SQL select * from member where id ...

  9. 关于SSM框架设置拦截器和过滤器

    我们知道拦截器和过滤器都是在项目中起到拦截过滤请求的功能,所以可能在设置的时候会傻傻分不清.这里我们先来比较它们的区别. 过滤器Filter是JavaEE标准,在Servlet的规范中定义的,是Ser ...

最新文章

  1. java 读取webservice_java 调用webService的各种方法
  2. SQL Server基础知识概念要点详细讲解
  3. HBase 默认配置项详细解读
  4. mysql 时间间隔分组_sql的两种以时间间隔分组的方法
  5. 什么是程控交换机?程控交换机有哪些优势?
  6. Emlog5.31后台登录页面自适应源码
  7. jquery-循环遍历
  8. 用QBE语言实现关系代数
  9. Regionals 2014 Asia - Daejeon
  10. linux wps2016_2016年十大Linux新闻报道
  11. 那些年我们遇到的坑(3)-basePackages和scanBasePackages
  12. 《神经网络与深度学习》-注意力机制与外部记忆
  13. 机顶盒boot分区读写
  14. Android开发笔记(序)写在前面的目录大全
  15. 200 PORT command successful. Consider using PASV / Linux 部署vsftp不能正常访问
  16. 隐私计算 — 区块链 — Overview
  17. 关于云码课堂 正在为学习迷茫的程序员进
  18. 使position:fixed不与其他div重叠 ,fixed所在div高度不变和可变两种情况
  19. 仿当当App首页按钮渐变动画效果
  20. 摄氏度转为华氏度的计算方法

热门文章

  1. Bootstrap入门(八)组件2:下拉菜单
  2. apache 静态编译和动态编译参考
  3. 关于Windows® API Code Pack for Microsoft® .NET Framework
  4. readonly和const的区别
  5. Teams App设备的地理位置能力
  6. 在Windows 7中的Windows Media Player 12中快速预览歌曲
  7. vue 入门notes
  8. 英语影视台词---八、the shawshank redemption
  9. Intellij IDEA2017 的控制台里不识别maven命令问题处理
  10. 你不知道的JavaScript(二)