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

发布于 2024-08-31 03:52:10 字数 642 浏览 6 评论 0原文

我正在多租户 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清引 2024-09-07 03:52:10

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

如果您希望 ITenantContext 成为该服务,它可能看起来像这样:

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

现在您的控制器可以依赖于您的存储库接口,并且您的存储库实现(任何其他关心的服务)可以依赖于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:

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

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.

追星践月 2024-09-07 03:52:10

@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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文