在 ASP.NET MVC 中使用 StructureMap 注入多租户存储库
我正在多租户 ASP.NET MVC 应用程序中实现 StructureMap,以注入基于 ITenantContext
接口检索数据的租户存储库实例。相关的Tenant
是根据基本控制器的
OnActionExecuting
中的RouteData
确定的。
如何告诉 StructureMap 构造 TenantContext(tenantID);
,其中tenantID 是从我的 RouteData
或某些基本控制器属性派生的?
基本控制器
给定以下路由:
{tenant}/{controller}/{action}/{id}
我的基本控制器根据 {tenant} URL 参数检索并存储正确的租户
。使用Tenant
,可以构建具有ITenantContext
的存储库,以仅检索与该租户相关的数据。
基于其他 DI 问题,AbstractFactory
可以作为解决方案吗?
I'm implementing StructureMap in a multi-tenant ASP.NET MVC application to inject instances of my tenant repositories that retrieve data based on an ITenantContext
interface. The Tenant
in question is determined from RouteData
in a base controller's OnActionExecuting
.
How do I tell StructureMap to construct TenantContext(tenantID);
where tenantID is derived from my RouteData
or some base controller property?
Base Controller
Given the following route:
{tenant}/{controller}/{action}/{id}
My base controller retrieves and stores the correct Tenant
based on the {tenant} URL parameter. Using Tenant
, a repository with an ITenantContext
can be constructed to retrieve only data that is relevant to that tenant.
Based on the other DI questions, could AbstractFactory
be a solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不要将租户存储在控制器上,因为正如您发现的那样,它不可用于注入的服务。创建一个瘦服务,其唯一职责是确定租户标识符。该服务可以直接访问静态数据和 HttpContext。这个类实际上不需要是可单元测试的——它的目的是隔离系统的其余部分,以便其他类是可测试的。
如果您希望 ITenantContext 成为该服务,它可能看起来像这样:
现在您的控制器可以依赖于您的存储库接口,并且您的存储库实现(任何其他关心的服务)可以依赖于
ITenantContext
。控制器不需要了解租户。Do not store the tenant on the controller, as it will not be available to injected services, as you discovered. Create a thin service whose sole responsibility is to determine the tenant identifier. The service can access statics and HttpContext directly. This class doesn't really need to be unit-testable - its purpose is to isolate the rest of the system so that other classes are testable.
If you want
ITenantContext
to be that service, it could look something like:Now your controller can just have a dependency on your repository interface, and your repository implementation (an any other services that care) can depend on
ITenantContext
. The controller doesn't need to know about tenants.@FreshCode,我不知道您是否直接在控制器中依赖于存储库,或者您的控制器是否依赖于服务,而服务又依赖于存储库。但是,当通过结构图实例化控制器时,服务或存储库应该已经实例化。我们确定 Begin_Request 上的租户,并使用 Inject 方法将实例化的上下文注入到结构图中。它在控制器工厂之前执行,因此当实例化控制器时,它的所有依赖项都已创建。
问候。
@FreshCode, I don´t know if you have a dependency on the repository directly in your controller or if your controller has a dependency on a service, which in turns, has a dependency on the repository. However, when the controller is instantiated by structuremap, the service or repository should be already instantiated. We determine the tenant on the Begin_Request and inject the instantiated context into structuremap, with the Inject method. That executes before the controller factory does, so when the controller is instantiated all it´s dependencies have already been created.
Regards.