entity-framework - 使用多个参数注册 DbContext
问题描述
我正在尝试将 TenantProvider 注入 DbContext
public class AppDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, long>
{
public int? _tenantId;
public ITenantProvider _tenantProvider;
public AppDbContext(
DbContextOptions<AppDbContext> options,
ITenantProvider tenantProvider
)
: base(options)
{
_tenantProvider = tenantProvider;
}
但我不明白如何正确注册它 - 如果我将断点放在构造函数中 -tenantProvider
是null
.
一点来自Startup.cs
services.AddDbContext<AppDbContext>(options => AppDbContextOptionsBuilder.Get());
需要下一行将其注入DbContext
控制器或服务(如果我将ServiceLifetime.Scoped
作为第二个参数添加到上述方法 - AddDbContext
- 该功能不起作用):
services.AddScoped(p => new AppDbContext(AppDbContextOptionsBuilder.Get(), p.GetService<ITenantProvider>()));
(Entity Framework
在我的解决方案中是一个单独的项目)
使用.AddScoped
方法时 - 我们可以通过TenantProvider
使用方法解析它来传递给构造函数.GetService
。
有谁知道如何解决TenantProvider
方法.AddDbContext
?
附加信息:
我试图ITenantProvider
在 with 的构造函数中DbContext
替换IHttpContextAccessor
- 后者被注册为单例。但acessor
参数仍然是null
。
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
解决方案
我真的不明白你的AddScoped
电话应该做什么。AddDbContext
将已经使用服务集合正确注册数据库上下文。所以当你通过依赖注入解析上下文时,额外的依赖会被自动解析。
所以这样做应该足够了:
services.AddDbContext<AppDbContext>(options => …);
services.AddSingleton<ITenantProvider, TenantProvider>();
然后,您可以依赖于AppDbContext
使用构造函数注入,例如在您的控制器中。
有两个注意事项:
配置选项时,应修改传递的选项对象。所以你不应该只返回
AppDbContextOptionsBuilder.Get()
,而是使用传递的选项对象并编辑它。您应该真正考虑您的数据库上下文依赖于您的租户提供者是否是正确的做法。根据SRP,您的数据库应该只做一件事情,那就是提供数据库访问。
根据您的租户提供者如何影响您的数据库访问,将这种依赖关系上移一层到使用数据库上下文和租户提供者以正确方式查询数据的某些服务中可能更有意义。
推荐阅读
- java - Gradle强制依赖版本?
- python - 返回列表,其中元素从轮流/python中的列表中获取
- javascript - WordPress || 提交或关闭表单时禁用弹出窗口制作工具的自动弹出窗口
- typescript - 将 SDF 计算为三角形网格的最有效方法
- nginx - 从 nginx prometheus exporter 获取更多数据
- web-component - 用于约束验证的自定义 Web 组件表单元素
- list - Prolog - 第一个列表是第二个列表的子列表,同时保持顺序?
- swift - 定时器过期后如何从 UIButton 移除焦点(tvOS)
- javascript - 按字母顺序对对象进行排序,同时将特定的键/值对作为第一项
- ios - 在 iOS 根进程(越狱设备)上发送 http/https 请求时崩溃