为什么我只在开发环境中遇到范围服务解析错误?

Bob*_*Bob 4 c# dependency-injection .net-core

我知道下面描述的错误的原因是我需要一个范围来实例化服务,这可以通过Services.CreateScope()匹配的.Dispose()/来完成using。问题是为什么我在开发和生产环境中得到不同的行为。


我有一个 .NET Core 3.1 控制台应用程序,它使用.NET 通用主机进行依赖项注入。在其中,我将 EF Core DbContext 定义为使用 进行数据库访问的范围服务AddDbContext,如下所示:

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        var configuration = hostContext.Configuration;

        services
            .AddDbContext<BotDbContext>(options =>
            {
                options
                    .UseLazyLoadingProxies()
                    .UseSqlite(configuration.GetConnectionString("Database"));
            });
    });
var db = host.Services.GetRequiredService<BotDbContext>();
Run Code Online (Sandbox Code Playgroud)

最初,我使用环境 ( DOTNET_ENVIRONMENT) as进行测试Production,这是默认情况。一切顺利。

我想要一个单独的Development环境,以更接近地模仿默认的 ASP.NET Core 模板。为此,我定义了一个调试时环境变量DOTNET_ENVIRONMENT=Development

当我这样做时,我收到以下异常:

System.InvalidOperationException:“无法从根提供程序解析范围服务“MyNamespace.Data.BotDbContext”。”

为什么只有环境有的时候才会出现这个异常Development,而没有呢Production

Bob*_*Bob 9

您已经使用创建了您的主机CreateDefaultBuilder。仔细查看文档,我们可以看到默认配置项之一:

当环境名称为“Development”时,在依赖项注入容器上启用范围验证

我们还可以在源代码中看到它ValidateScopes仅在开发环境中对ServiceProvider进行设置。

通过此配置,在开发环境之外,配置的 ServiceProvider 将很乐意返回范围上下文之外的范围服务(尽管这永远不应该依赖;这些服务的范围是有原因的!)。