当环境是“本地”而不是“开发”时,为什么可以从根范围解析 DbContext?

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

为什么我需要创建一个范围来解析

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;
    }
}
c# .net entity-framework-core azure-functions
1个回答
0
投票

没有看到完整的设置,这有点猜测,但通常会发生这种情况,因为对于开发环境

ServiceProviderOptions.ValidateScopes
已启用(出于性能原因,默认情况下在其他环境中禁用):

true
如果执行验证以确保范围服务不会从根提供者解析;否则为假。默认值为
IsDevelopment(IHostingEnvironment)
的值。

由于默认情况下

AddDbContext
/
AddDbContextFactory
将上下文注册为作用域,因此验证将失败(请参阅captive-dependency),正确的方法是创建一个作用域并处置它,或者使用工厂并在使用它后处置上下文。

© www.soinside.com 2019 - 2024. All rights reserved.