Autofac multitenant - 在运行时覆盖租户
Autofac multitenant - override tenant in runtime
我有一个使用 Autofac 多租户容器的 .net 核心 Web 应用程序。
租户策略通过查看HTTP请求的路径来解析租户。
但是,有一个特定的功能,其中租户A需要使用另一个租户B(在本例中为子租户)的配置;问题是直到租户A已经执行了一些逻辑才知道它需要使用哪个子租户的配置。
有没有办法在运行时获取另一个租户的服务?
我会试着用一个例子来说明:
我拥有的大概是:
- 对 GET my.host.net/A/rules
的 HTTP 请求
- 租户解析器能够识别当前租户是A(它在路径中,就在主机名之后)
- 租户解析器从数据库中获取通用规则,其中一条表示应该使用另一个租户B的配置
- 以后我要使用租客B的服务
我尝试/想到的是什么?
- 保存多租户容器并使用 GetTenantScope 来解析 class 工厂中租户 B 的范围,该工厂解析要使用的服务。但是,我不知道内存使用方面的影响以及混合租户可能出现的问题
- 忘掉多租户,只在特定 class.
中保存每个租户的配置
我不确定在这种情况下“分租户”是什么意思。 Autofac 在其多租户支持中没有多级租户的概念,因此虽然这种构造在 您的应用程序 的上下文中可能有意义,但试图在 Autofac 中实现它不会简单
尝试在请求中更换租户充其量是一个挑战。通过请求管道(中间件、控制器等)的事物都将要使用在请求中首先设置的 HttpContext.RequestServices
。就像,它实际上是第一个运行的中间件。一旦设置好,管道开始解析,控制器和其他东西开始解析,然后……它被锁定在那个租户中。你不能切换它。
鉴于此,我提醒您不要尝试从一个租户那里解决一些问题,切换中间请求,然后从另一个租户那里解决其余问题。您可能会遇到不一致的情况。
假设您有一个采用 ISomeCoolService
的中间件实例。您还有一个需要 ISomeCoolService
的控制器,但您在控制器中使用了特殊的租户切换逻辑,而不是将其作为依赖项。在中间件执行期间,中间件将获得租户 A 的 ISomeCoolService
,但控制器将使用租户 B 的 ISomeCoolService
,现在应用程序行为不一致。尝试确保与租户切换的一致性将非常非常困难。
以下是我的推荐:
- 如果您可以在
ITenantIdentificationStrategy
中预先确定所有租户 并将其缓存在 HttpContext.Items
中,那么您就没有再次查找 - 这样做。使用初始租户确定逻辑,管道中的第一次点击可能会很慢,但之后 ITenantIdentificationStrategy
可以在 HttpContext.Items
中查找租户 ID,而不是进行数据库调用,这会很快。这将使您不必在请求中切换租户。
- 如果您不能预先确定租户并且您需要管道执行一段时间才能弄清楚......您可能需要不同的方式来确定承租人。确实,尽量避免更换租户。它会永远给你带来微妙的问题。
- 不要试图让“租户继承”工作, 至少在现有的 Autofac Multitenant 支持下不要这样做。我知道说“一些服务是租户 A 但其他服务是租户 B 并且它沿堆栈向下继承”会很好,但这不是多租户支持中内置的东西,并且很难尝试强制工作。
如果您真的、真的、真的只是致力于让这个租户“层次结构”正常工作,您可以尝试分叉 Autofac.Multitenant 支持和 implementing a new MultitenantContainer
that allows for sub-tenants。 MultitenantContainer
的逻辑实际上并没有那么复杂,它只是为每个租户存储一个标记的生命周期范围。假设您可以添加一些功能来启用子租户配置。这不会是五分钟的工作,而且它并不是我们真正计划添加到 Autofac 的东西,所以这将是您拥有的一个完整的叉子,但您可以做到。
我有一个使用 Autofac 多租户容器的 .net 核心 Web 应用程序。 租户策略通过查看HTTP请求的路径来解析租户。
但是,有一个特定的功能,其中租户A需要使用另一个租户B(在本例中为子租户)的配置;问题是直到租户A已经执行了一些逻辑才知道它需要使用哪个子租户的配置。
有没有办法在运行时获取另一个租户的服务?
我会试着用一个例子来说明:
我拥有的大概是:
- 对 GET my.host.net/A/rules 的 HTTP 请求
- 租户解析器能够识别当前租户是A(它在路径中,就在主机名之后)
- 租户解析器从数据库中获取通用规则,其中一条表示应该使用另一个租户B的配置
- 以后我要使用租客B的服务
我尝试/想到的是什么?
- 保存多租户容器并使用 GetTenantScope 来解析 class 工厂中租户 B 的范围,该工厂解析要使用的服务。但是,我不知道内存使用方面的影响以及混合租户可能出现的问题
- 忘掉多租户,只在特定 class. 中保存每个租户的配置
我不确定在这种情况下“分租户”是什么意思。 Autofac 在其多租户支持中没有多级租户的概念,因此虽然这种构造在 您的应用程序 的上下文中可能有意义,但试图在 Autofac 中实现它不会简单
尝试在请求中更换租户充其量是一个挑战。通过请求管道(中间件、控制器等)的事物都将要使用在请求中首先设置的 HttpContext.RequestServices
。就像,它实际上是第一个运行的中间件。一旦设置好,管道开始解析,控制器和其他东西开始解析,然后……它被锁定在那个租户中。你不能切换它。
鉴于此,我提醒您不要尝试从一个租户那里解决一些问题,切换中间请求,然后从另一个租户那里解决其余问题。您可能会遇到不一致的情况。
假设您有一个采用 ISomeCoolService
的中间件实例。您还有一个需要 ISomeCoolService
的控制器,但您在控制器中使用了特殊的租户切换逻辑,而不是将其作为依赖项。在中间件执行期间,中间件将获得租户 A 的 ISomeCoolService
,但控制器将使用租户 B 的 ISomeCoolService
,现在应用程序行为不一致。尝试确保与租户切换的一致性将非常非常困难。
以下是我的推荐:
- 如果您可以在
ITenantIdentificationStrategy
中预先确定所有租户 并将其缓存在HttpContext.Items
中,那么您就没有再次查找 - 这样做。使用初始租户确定逻辑,管道中的第一次点击可能会很慢,但之后ITenantIdentificationStrategy
可以在HttpContext.Items
中查找租户 ID,而不是进行数据库调用,这会很快。这将使您不必在请求中切换租户。 - 如果您不能预先确定租户并且您需要管道执行一段时间才能弄清楚......您可能需要不同的方式来确定承租人。确实,尽量避免更换租户。它会永远给你带来微妙的问题。
- 不要试图让“租户继承”工作, 至少在现有的 Autofac Multitenant 支持下不要这样做。我知道说“一些服务是租户 A 但其他服务是租户 B 并且它沿堆栈向下继承”会很好,但这不是多租户支持中内置的东西,并且很难尝试强制工作。
如果您真的、真的、真的只是致力于让这个租户“层次结构”正常工作,您可以尝试分叉 Autofac.Multitenant 支持和 implementing a new MultitenantContainer
that allows for sub-tenants。 MultitenantContainer
的逻辑实际上并没有那么复杂,它只是为每个租户存储一个标记的生命周期范围。假设您可以添加一些功能来启用子租户配置。这不会是五分钟的工作,而且它并不是我们真正计划添加到 Autofac 的东西,所以这将是您拥有的一个完整的叉子,但您可以做到。