.net-core - Autofac 多租户 - 在运行时覆盖租户
问题描述
我有一个使用 Autofac 多租户容器的 .net 核心 Web 应用程序。租户策略通过查看 HTTP 请求的路径来解析租户。
但是,有一个特定的功能,租户 A 需要使用另一个租户 B(在这种情况下为子租户)的配置;问题是直到租户 A 已经执行了一些逻辑来知道它需要使用哪个子租户的配置时才知道。
有没有办法在运行时获取另一个租户的服务?
我将尝试用一个例子来澄清:
我所拥有的或多或少是:
- GET my.host.net/A/rules 的 HTTP 请求
- 租户解析器能够识别当前租户是 A(它在路径中,就在主机名之后)
- 租户解析器从数据库中获取通用规则,其中一个表示应该使用另一个租户 B 的配置
- 从这里开始,我想使用租户 B 的服务。
我尝试过/想到了什么?
- 保存 Multitenant 容器并使用 GetTenantScope 在解析要使用的服务的类工厂中解析租户 B 的范围。但是,我不知道在内存使用方面的影响以及混合租户可能出现的问题
- 忘记多租户,只需将每个租户的配置保存在特定的类中。
解决方案
我不确定在这种情况下“子租户”是什么意思。Autofac 在其多租户支持中没有多级租户的概念,因此虽然这种结构在您的应用程序的上下文中可能是有意义的,但尝试在 Autofac中使其工作并不容易。
尝试在请求中切换租户充其量将是一个挑战。通过请求管道的事物(中间件、控制器等)都将要使用HttpContext.RequestServices
在请求中设置的第一件事。就像,它实际上是第一个运行的中间件。设置好后,管道开始解析,控制器和其他东西开始解析,并且......它被锁定到该租户中。你不能切换它。
鉴于此,我会提醒您不要尝试从一个租户解决某些问题、切换中间请求并从其他租户解决其余问题。您很可能会遇到不一致的情况。
假设你有一个中间件实例,它需要一个ISomeCoolService
. 您还有一个需要 的控制器ISomeCoolService
,但您在控制器中使用了特殊的租户切换逻辑,而不是将其作为依赖项。在中间件执行期间,中间件将获得租户 A,ISomeCoolService
但控制器将使用租户 B ISomeCoolService
,现在您的应用程序行为不一致。试图确保与租户切换的一致性将非常非常困难。
这是我的建议:
- 如果您可以预先确定所有租户并将其
ITenantIdentificationStrategy
缓存在其中,HttpContext.Items
那么您不必再次查找它 - 这样做。最初的租户确定逻辑在管道中的第一次命中可能会很慢,但之后ITenantIdentificationStrategy
可以查找HttpContext.Items
租户 ID 而不是进行数据库调用,它会很快。这将阻止您在请求中切换租户。 - 如果您无法预先确定租户,并且您需要管道执行一段时间才能弄清楚......您可能需要一种不同的方式来确定租户。真的,尽量避免更换租户。它会永远给你带来微妙的问题。
- 不要试图让“租户继承”工作,至少不要使用股票 Autofac Multitenant 支持。我认识到说“某些服务是租户 A,而其他服务是租户 B,并且它会沿堆栈继承”会很好,但这不是多租户支持中内置的东西,而且很难试图强制工作。
如果您真的,真的,真的只是致力于让这个租户“层次结构”工作,您可以尝试分叉 Autofac.Multitenant 支持并实施一个MultitenantContainer
允许子租户的新功能。的逻辑MultitenantContainer
实际上并没有那么复杂,它只是为每个租户存储一个标记的生命周期范围。假设您可以添加一些功能来启用子租户配置。这不会是五分钟的工作,也不是我们计划添加到 Autofac 中的东西,所以这将是一个你可以拥有的完全分支,但你可以做到。
推荐阅读
- ios - UIView 关键帧动画时间不符合预期
- android - Android中错误处理的更好方法
- javascript - 如何有效地将预定义大小的大块分割成较小的块,这些块是 JavaScript 中大小的因素?
- amazon-web-services - SSH 在一个 EC2 实例中失败,但在另一个实例中有效
- android - 无法定位开发设备;请运行“颤振医生”以获取有关安装其他组件的信息。关于 VS 代码
- python - 什么是烧瓶 python 中的 pycache 文件夹?
- php - 对表PHP中的多维数组进行排序
- codeigniter - 忘记密码不发送电子邮件验证(Codeigniter)
- javascript - JavaScript 中奇怪的数组行为
- jquery - 删除子表上的过滤器(jquery)