.net core控制台应用程序中AddScoped和AddSingleton有什么区别?

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

ASP.NET 上下文中

AddScoped
的范围是可以理解的,即在请求级别。当涉及到控制台应用程序时,它没有请求上下文,对吗?它会表现如何?

services.AddScoped<SomeServiceClass>();
services.AddSingleton<SomeServiceClass>();

c# .net .net-core console-application
3个回答
3
投票

在控制台应用程序中,没有像 Web 上下文中那样的内置请求概念。因此,如果您在控制台应用程序中使用依赖项注入 (DI),则必须手动管理服务范围。

    using (var scope = serviceProvider.CreateScope())
{
    var service = scope.ServiceProvider.GetRequiredService<SomeServiceClass>();
    // use service here
}

单例的行为是一样的


0
投票

尽管这与 Web 应用程序的依赖注入不同。概念保持不变。

添加范围:

  • 每个范围服务创建一次。在 Web 应用程序的上下文中,这通常意味着每个 HTTP 请求一次。
  • 在控制台应用程序性质中,范围可能与特定操作相关。

添加单例:

  • 服务仅创建一次,并在应用程序的生命周期内重复使用
  • 在控制台应用程序中,这意味着服务在以下情况下创建: 首先被请求并在整个持续时间内重复使用 申请。

0
投票

在请求级别。当涉及到控制台应用程序时,它没有请求上下文,对吧?

是的,在 ASP.NET Core 框架中将根据请求创建范围。在控制台应用程序中,没有开箱即用的“请求”概念,但您可以在需要时手动创建范围(当您进行一些迭代和/或长时间运行的处理时,例如涉及 EF Core

DbContext
时,这可能会很有用):

var services = new ServiceCollection();
// services.Add...
var serviceProvider = services.BuildServiceProvider();

while (some_condition)
{
    using var scope = serviceProvider.CreateScope();

    var service = scope.ServiceProvider.GetRequiredService<ISomeService>();
    service.DoSomething();
}

启用范围验证后,无法从根范围解析范围服务的主要区别(这样做是为了防止类似于强制依赖项“引入”的负面影响):

var services = new ServiceCollection();
// services.Add...
services.AddScoped<object>();
var serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions
{
    ValidateScopes = true, // can be detrimental for perf, disable on Prod
    // ValidateOnBuild = true
});

// InvalidOperationException: Cannot resolve scoped service 'System.Object' from root provider:
var service = serviceProvider.GetRequiredService<object>();
© www.soinside.com 2019 - 2024. All rights reserved.