在Web的情况下,每个请求都是不同的作用域,注册为作用域的依赖关系将在每个请求中得到解决。因此,解决每个租户每个请求的依赖关系很容易,因为可以在中传递租户信息(如TenantId),如下所示:
services.TryAddScoped<ITenantContext>(x =>
{
var context = x.GetService<IHttpContextAccessor>().HttpContext;
var tenantId = context.Request.Headers["TenantId"].ToString();
var tenantContext = GetTenantContext(tenantId);
return tenantContext;
}其他注册首先解析TenantContext并使用它解决其他依赖关系。例如,IDatabase将注册如下。在解析过程中,它将解析并连接到特定的租户数据库。
services.TryAddScoped<IDatabase>(x =>
{
var tenantContext = x.GetService<ITenantContext>();
return new Database(tenantContext.DatabaseConnectionString);
}这在Web服务中是很好的,因为每个请求都是一个作用域。我面临在多租户控制台应用程序中使用依赖注入的挑战。假设应用程序处理多租户队列中的项目,并且每条消息可以属于不同的租户。在处理每条消息时,它将数据提交给特定于租户的数据库。因此,在本例中,作用域是队列中的每个消息,消息包含tenantId。
因此,当应用程序从队列中读取消息时,它需要获取TenantContext。然后基于此TenantContext解决其他依赖关系。
我看到如何实现这个动态解析的一个简单的选择是使用TenantContext手动创建依赖对象,但这样我就无法利用依赖注入。在消息处理之后,所有对象都将在超出作用域后手动创建和释放。
var messgage = GetMessageFromQueue(queueName);
var tenantContext = GetTenantContext(message.TenantId);
var database = GetDatabaseObject(tenantContext);
// Do other processing now we got the database object connected to specific tenant DB在DI中是否有一个选项,我可以动态地传递TenantId,以便为这个作用域设置TenantContext,然后在这个范围内进行进一步的解析利用这个TenantContext。
发布于 2022-02-11 18:10:58
由于租约的角色超出了实现(“此使用X数据库”),实际上与正在执行的操作(“它使用X数据库,必须根据操作中处理的上下文使用此连接字符串”)有关联,因此存在一些风险,即假定环境上下文存在于替代实现中,因为它没有在接口中以某种方式明确描述,这就是DI问题出现的地方。
你也许可以:
公共接口ITenantDatabase {公共TResponse Get(string TenantId,int );//.其他方法. }
公共接口ITenantDatabaseFactory { public IDatabase GetDatabaseForTenant(int TenantId);} //添加手动生成和返回作用域对象的实现
https://stackoverflow.com/questions/71081028
复制相似问题