1 回答
TA贡献1871条经验 获得超8个赞
您可以使用工厂重载来AddScoped
实现您希望每个租户/请求都不同的服务。这是一个例子:
services.AddScoped<IServiceForTenant>(sp =>
{
var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>();
var serviceForTenant = new ServiceForTenant();
// TODO: Use httpContextAcccessor.HttpContext to configure serviceForTenant.
return serviceForTenant;
});
对于进入 ASP.NET Core 应用程序的每个请求,上面的代码将在您首次IServiceForTenant在控制器中发出请求时运行。此时,您的代码可以读取IHttpContextAccessor.HttpContext并做出所需的任何决策,以便为IServiceForTenant. 然后,该相同的实例将用于请求的其余部分(即管道的更上游)。
传入的参数AddScoped是Func<IServiceProvider, T>. 您需要在这里提供某种委托,这可以通过多种方式之一来完成。以下是一些示例:
您可以将调用包装到其自己的扩展方法中,如下所示:
public static void AddServiceForTenant(this IServiceCollection services)
{
services.AddScoped<IServiceForTenant>(sp =>
{
// ...
});
}
在ConfigureServices:
services.AddServiceForTenant();
使用带有方法的类static:
public static class ServiceForTenantFactory
{
public static ITenantForService Create(IServiceProvider sp)
{
// ...
}
}
在ConfigureServices:
services.AddScoped(ServiceForTenantFactory.Create);
使用带有实例方法的类:
public class ServiceForTenantFactory
{
public ITenantForService Create(HttpContext httpContext)
{
// ...
}
}
在ConfigureServices:
services.AddScoped(sp =>
{
var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>();
var serviceForTenantFactory = new ServiceForTenantFactory(); // Or use DI.
return serviceForTenantFactory.Create(httpContextAccessor.HttpContext);
});
最后一个选项是最灵活的,因为您甚至可以ServiceForTenantFactory从 DI 解析自身,并且它可以有自己的依赖项等。另请注意,Create这里直接采用HttpContext(作为示例)。
正如我已经说过的,还有比所示的三个更多的选项,但这应该是一个很好的使用基础。
- 1 回答
- 0 关注
- 97 浏览
添加回答
举报