6

我正在多租户 ASP.NET MVC 应用程序中实现 StructureMap,以注入基于接口检索数据的租户存储库的实例。ITenantContextTenant问题的是从RouteData基本控制器的 OnActionExecuting.

如何告诉 StructureMap 构建TenantContext(tenantID);从我的RouteData或某些基本控制器属性派生的tenantID 的位置?

基本控制器

给定以下路线:

{tenant}/{controller}/{action}/{id}

Tenant我的基本控制器根据 {tenant} URL 参数检索并存储正确的。使用,可以构造Tenant带有 的存储库,以仅检索与该租户相关的数据。ITenantContext

基于其他 DI 问题,可能AbstractFactory是一个解决方案吗?

4

2 回答 2

7

不要将租户存储在控制器上,因为正如您所发现的那样,注入的服务将无法使用它。创建一个瘦服务,其唯一职责是确定租户标识符。该服务可以直接访问静态和 HttpContext。这个类实际上不需要是可单元测试的——它的目的是隔离系统的其余部分,以便其他类是可测试的。

如果你想ITenantContext成为那个服务,它可能看起来像:

public class TenantContext : ITenantContext
{
    public string GetTenant()
    {
        var routeData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(HttpContext.Current));
        return routeData.GetRequiredString("tenant");
    }
}

现在您的控制器可以只依赖于您的存储库接口,并且您的存储库实现(任何其他关心的服务)可以依赖于ITenantContext. 控制器不需要了解租户。

于 2010-05-03T03:30:35.217 回答
1

@FreshCode,我不知道您是否直接在控制器中依赖于存储库,或者您的控制器是否依赖于服务,而服务又依赖于存储库。但是,当通过结构映射实例化控制器时,服务或存储库应该已经实例化。我们在 Begin_Request 上确定租户,并使用 Inject 方法将实例化的上下文注入到结构映射中。这在控制器工厂之前执行,因此当控制器被实例化时,它的所有依赖项都已经创建。

问候。

于 2010-05-01T15:15:56.377 回答