在ASP.NET MVC中使用StructureMap注入多租户存储库

时间:2010-05-01 12:43:59

标签: asp.net-mvc routing structuremap multi-tenant repository

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

如何告诉StructureMap构建TenantContext(tenantID);,其中tenantID是从我的RouteData或某个基本控制器属性派生的?

基本控制器

考虑以下路线:

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

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

根据其他DI问题,AbstractFactory可以成为解决方案吗?

2 个答案:

答案 0 :(得分:7)

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

如果您希望ITenantContext成为该服务,它可能类似于:

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

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

答案 1 :(得分:1)

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

问候。