.NET Core DI 允许将作用域服务注入到本地计算机上的单例中

LP1*_*P13 8 c# asp.net-core-mvc asp.net-core

我在 Startup.cs 中有以下代码

\n
    public void ConfigureServices(IServiceCollection services)\n    {\n        // EF\n        services.AddDbContext<MyDatabaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));\n\n        // domain services            \n        services.AddScoped<ILookupService, LookupService>();\n        \n        services.AddMemoryCache();\n\n        // singleton\n        services.AddSingleton<CacheManager>();            \n    }\n\n\npublic class CacheManager\n{\n    private readonly ILookupService _lookupService;\n    private readonly IMemoryCache _cache;\n    public CacheManager(ILookupService lookupService, IMemoryCache cache)\n    {\n        _lookupService = lookupService;\n        _cache = cache;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

当我在开发服务器上部署应用程序并尝试访问时。我看到异常

\n
\n

AggregateException:无法构造某些服务\n(验证服务描述符“ServiceType:\nUI.Helpers.CacheManager 生命周期:单例\nImplementationType:UI.Helpers.CacheManager”时出错\n:无法\n使用作用域服务\n“ApplicationCore” .Services.ILookupService'来自\nsingleton'UI.Helpers.CacheManager'。)

\n
\n

请注意,我理解为什么会发生这种情况,我会解决它。基本上,您无法将较小范围的服务注入到较大范围的服务中。ASP.NET Core 的 DI 试图确保您不\xe2\x80\x99t 这样做。

\n

我不明白为什么当我在 VS 中本地运行应用程序时没有看到这个问题?

\n

yv9*_*89c 2

我今天搬起石头砸自己的脚时就遇到了这个问题。

根据文档, WebHost.CreateDefaultBuilder的实现仅在环境为 时才将ServiceProviderOptions.ValidateScopes设置为。例如,默认情况下,如果以下任何环境变量设置为: , . 我也通过Host.CreateDefaultBuilder得到相同的行为。trueDevelopmentDevelopmentASPNETCORE_ENVIRONMENTDOTNET_ENVIRONMENT

设置ServiceProviderOptions.ValidateScopes为 时false,将作用域服务注入单例服务不会给我带来运行时错误,而是通过某种形式的瞬态行为解决依赖关系。

我只能想象此设置的存在是为了避免在更高环境中执行这些验证的开销。对我来说,在开发时这样做似乎就足够了。

只是重申@LP13 已经说过的话。将作用域服务注入单例服务是无效的。为此,您必须在单例实例内创建一个范围。

我引用的是 .NET Core 3.1 文档,但从 .NET 6 开始仍然如此。

范围验证文档