简体   繁体   English

在 startup.cs ConfigureServices 或 program.cs Main 方法中在 .NET Core 3.+ 中注册 IHostedService 时有区别吗?

[英]Is there a difference when registering an IHostedService in .NET Core 3.+ in the startup.cs ConfigureServices or in program.cs Main method?

I'm playing around with trying to use IHostedServices in a 3.1 .NET Core web application.我正在尝试在 3.1 .NET Core web 应用程序中使用 IHostedServices。

I can see that I can register them in 2 different places:我可以看到我可以在 2 个不同的地方注册它们:

  • program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        })
        .ConfigureServices(services =>
        {
            services.AddHostedService<BackgroundServiceA>();
            services.AddHostedService<BackgroundServiceB>();
        });

or in the ConfigureServices method in startup.cs或在startup.csConfigureServices方法中

public void ConfigureServices(IServiceCollection services)
{
    services.AddHostedService<BackgroundServiceA>();
}

I'm under the impression that both of these are identical.我的印象是这两者是相同的。 And if they are, does one override the other, if both exist?如果它们是,如果两者都存在,是否会覆盖另一个?

I'm under the impression that both of these are identical.我的印象是这两者是相同的。

Yes, both approaches inject a delegate into the logic used to build an IServiceProvider .是的,这两种方法都将委托注入到用于构建IServiceProvider的逻辑中。 Whether you do this via the IHostBuilder or the Startup class, the result is the same.无论您是通过IHostBuilder还是Startup class 执行此操作,结果都是一样的。

Does one override the other, if both exist?如果两者都存在,是否会覆盖另一个?

The answer to this depends on two things:这个问题的答案取决于两件事:

  1. The order in which you've registered the delegates.您注册代表的顺序。
  2. The details of the registration itself.注册本身的详细信息。

To make it easier to explain, here's the code copied from your question:为了更容易解释,这是从您的问题中复制的代码:

 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }).ConfigureServices(services => { services.AddHostedService<BackgroundServiceA>(); services.AddHostedService<BackgroundServiceB>(); });
 public void ConfigureServices(IServiceCollection services) { services.AddHostedService<BackgroundServiceA>(); }

This shows an order that goes like this:这显示了这样的顺序:

  1. Startup.ConfigureServices , because ConfigureWebHostDefaults is called first. Startup.ConfigureServices ,因为首先调用ConfigureWebHostDefaults
  2. IHostBuilder.ConfigureServices

This means the registration in your Startup class runs first;这意味着您的Startup class 中的注册首先运行; followed by the registration performed via IHostBuilder.ConfigureServices in the Program class.然后通过Program IHostBuilder.ConfigureServices中的 IHostBuilder.ConfigureServices 执行注册。

If you switch the order of those two calls, you also switch the order of the registrations:如果你切换这两个调用的顺序,你也会切换注册的顺序:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices(services =>
        {
            services.AddHostedService<BackgroundServiceA>();
            services.AddHostedService<BackgroundServiceB>();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

With this change, the registration performed via IHostBuilder.ConfigureServices runs first.通过此更改,首先运行通过IHostBuilder.ConfigureServices执行的注册。

AddHostedService uses TryAddEnumerable behind the scenes. AddHostedService在幕后使用TryAddEnumerable If TryAddEnumerable is called with a TService to TImplementation pair that already exists in the service collection, it's ignored.如果TryAddEnumerable使用已存在于服务集合中的TServiceTImplementation对来调用,则会被忽略。 Consider the following example, slightly adapted from the code in your question:考虑以下示例,稍微改编自您问题中的代码:

services.AddHostedService<BackgroundServiceA>();
services.AddHostedService<BackgroundServiceA>();

services.AddHostedService<BackgroundServiceB>();

The first call to add BackgroundServiceA succeeds, registering BackgroundServiceA against the IHostedService interface.添加BackgroundServiceA的第一次调用成功,将BackgroundServiceA注册到IHostedService接口。 The second time it's called, nothing happens, because this pair has already been registered.第二次调用时,什么也没有发生,因为这对已经注册了。

The first call to add BackgroundServiceB also succeeds.添加BackgroundServiceB的第一次调用也成功。 Although this is using the same interface, IHostedService , it's a different implementation that's being registered, and so it's a different pair.尽管这是使用相同的接口IHostedService ,但它是一个不同的实现,正在注册,因此它是不同的对。

All of this means that the registration in your Startup.ConfigureServices is the one that will be used.所有这一切都意味着您的Startup.ConfigureServices中的注册将被使用。 This is because it runs first and because later registration ends up as a no-op.这是因为它首先运行并且因为后来的注册最终成为无操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .NET Core program.cs 和 Startup.cs 未命中 - .NET Core program.cs and Startup.cs not hit 当调用ConfigureServices和Configure方法时,在startup.cs中的asp.net core mvc(dotnet 5)中? - in asp.net core mvc (dotnet 5) in startup.cs when ConfigureServices and Configure method called? 只要ASP.NET Core中有可用的program.cs / startup.cs,即可获取当前URL - Get Current URL as soon as available program.cs / startup.cs in ASP.NET Core ASP.NET 内核在 Program.cs 和 Startup.cs 中捕获并显示错误 - ASP.NET Core catch and display error inside Program.cs and Startup.cs ASP.NET Core 2 中的 Startup.cs 与 Program.cs - Startup.cs vs Program.cs in ASP.NET Core 2 .NET核心从Program.cs传递命令行Args到Startup.cs - .NET core Pass Commandline Args to Startup.cs from Program.cs ConfigureServices方法中的ASP.NET Core 1.0访问服务(Startup.cs) - ASP.NET Core 1.0 access service in ConfigureServices method (Startup.cs) 在Startup.cs中使ConfigureServices方法异步 - Make the ConfigureServices method async in Startup.cs ASP.NET Core 在 Startup.cs ConfigureServices 方法中访问服务 - ASP.NET Core access service in Startup.cs ConfigureServices method 如何在startup.cs的ConfigureServices方法中正确注入DbContext实例(ASP.net core 1.1)? - How to inject DbContext instance in the ConfigureServices method of startup.cs correctly (ASP.net core 1.1)?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM