为什么我需要创建一个范围来解析
DbContext
,只有当 DOTNET_ENVIRONMENT
不是“本地”时?
当环境设置为“开发”时,我需要使用范围:
DbContext
来解决using var scope = host.Services.CreateScope()
,因为我收到以下错误而没有:
无法解析范围服务“foo.bar.baz.AssetGovernanceContext” 来自根提供商。
但是当
DOTNET_ENVIRONMENT
设置为“本地”时,我可以从根提供程序解析 DbContext
(即不需要范围)。
是否有根提供者通常用于解析单例的提供者?
# Add DbContext to service collection
services.AddDbContext<AssetGovernanceContext>(options =>
{
var connectionString = configuration.GetConnectionString("SqlServer") ?? throw new ConfigurationErrorsException("Connection string not found: SqlServer");
options.UseSqlServer(connectionString);
});
# Resolve the DbContext after calling IHost.Build()
public static class HostExtensions
{
public static IHost EnsureDatabaseCreated(this IHost host)
{
var createDatabase = host.Services.GetRequiredService<IConfiguration>().GetValue<bool>("Database:EnsureCreated");
if (createDatabase)
{
using var scope = host.Services.CreateScope(); # only needed if DOTNET_ENIRONMENT isn't "local"
var dbContext = scope.ServiceProvider.GetRequiredService<AssetGovernanceContext>();
dbContext.Database.EnsureCreated();
}
return host;
}
}
没有看到完整的设置,这有点猜测,但通常会发生这种情况,因为对于开发环境
ServiceProviderOptions.ValidateScopes
已启用(出于性能原因,默认情况下在其他环境中禁用):
如果执行验证以确保范围服务不会从根提供者解析;否则为假。默认值为true
的值。IsDevelopment(IHostingEnvironment)
由于默认情况下
AddDbContext
/AddDbContextFactory
将上下文注册为作用域,因此验证将失败(请参阅captive-dependency),正确的方法是创建一个作用域并处置它,或者使用工厂并在使用它后处置上下文。