ASP.NET Core 6 中的租户特定容器

问题描述 投票:0回答:1

我在 ASP.NET Core 6 中构建了多租户架构,我想创建一个像 MessageService 这样的服务实例,它是应该为每个租户隔离的单例服务。问题是当我进行依赖注入时,有 3 个生命周期范围是

Singleton
Transient
Scope

对于 Transient 和 Scope,它会在每次请求到来时创建新实例,而 Singleton 它将创建 1 次,但它会与所有租户混合

我的问题是如何使用 Autofac 或使用任何其他框架/库在 asp.net core 6 中创建类似于每个租户的 Singleton 的服务实例?或者简而言之:我想在 ASP.NET Core 6 中创建特定于租户的容器。

c# asp.net autofac multi-tenant asp.net-core-6.0
1个回答
1
投票

内置 DI 不支持 keyed dependencies/injection based on name 所以你基本上有两个选择 - 切换到另一个支持它的容器(例如 Autofac - 和 my take on factory with it)或者创建一个工厂。使用

Func
工厂的第二种方法的简单示例如下所示(假设租户对于应用程序运行是静态的,动态可以通过类似的方式进行小的修改):

interface ISomeTenantService
{
    public int TenantId { get; } // possibly move to another interface for interface segregation
    public void SomeMethod();
}

class SomeTenantServiceParams
{
   // all required deps here
}

class SomeTenantService : ISomeTenantService
{
    public SomeTenantService(int tenantId, SomeTenantServiceParams p)
    {
        TenantId = tenantId;
        // flatten and assign SomeTenantServiceParams
        // ...
    }
    
    public int TenantId { get; }

    public void SomeMethod()
    {
        throw new NotImplementedException();
    }
}

// registration:
int[] tenants = { 1, 2 }; // supported tenants
services.AddSingleton<SomeTenantServiceParams>();
foreach (var tenantId in tenants)
{
    services.AddSingleton<ISomeTenantService>(sp =>
        new SomeTenantService(tenantId, sp.GetRequiredService<SomeTenantServiceParams>()));
}

services.AddSingleton<Func<int, ISomeTenantService>>(sp =>
{
    var all = sp.GetRequiredService<IEnumerable<ISomeTenantService>>();
    var lookup = all.ToDictionary(s => s.TenantId);
    return i => lookup[i];
});

然后在需要的地方注入

Func<int, ISomeTenantService>
工厂并简单地使用它:

Func<int, ISomeTenantService> _factory = ...; // injected

var forFirstTenant = _factory(1);
© www.soinside.com 2019 - 2024. All rights reserved.