为什么注册IHostedService时无法实例化HomeController

时间:2019-11-12 03:25:12

标签: asp.net-core-3.0

我一直在努力尝试使它工作,但我似乎什么也没尝试。

总结一下,我正在尝试:
1)注册为单例,这是我的一项服务,该服务由IHostedService包装器启动
2)在启动应用程序时实例化了我的HomeController并注入了上述服务

我从以下内容开始,并尝试了各种版本,但无济于事:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddSingleton<IRunnerA, RunnerA>();
    services.AddSingleton<IRunnable>
    (
        services => services.GetRequiredService<IRunnerA>()
        // services => services.GetService<IRunnerA>() does not work either
    );

    services.AddSingleton<IHostedService, RunnableWrapper>(); // the IHostedService wrapper
}


虽然RunnableWrapper确实会在应用启动时启动(即,其StartAsync被调用),但我下面的HomeController从未实例化:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private IRunnerA _runnerA;

    public HomeController
    (
        ILogger<HomeController> logger,
        IRunnerA runnerA
    )
    {
        // Never reaches here while debugging, given the above services config.
    }

问题:为什么我的HomeController没有被实例化?

===

其他信息:
在尝试过的许多事情中,我还尝试了此处建议的内容:https://stackoverflow.com/a/52398431,但是我仍然得到相同的行为。

观察

  1. 很奇怪,如果我删除行services.AddSingleton<IHostedService, RunnableWrapper>();,那么我的HomeController确实会在应用启动时实例化。
  2. 如果我从RunnableWrapper的{​​{1}}方法返回而未在其中执行长时间运行的操作(我认为这是后台服务的重点),那么我的public async Task StartAsync(CancellationToken cancellationToken)会执行实例化。

1 个答案:

答案 0 :(得分:0)

问题似乎在于在IHostedService中的ConfigureServices中注册了Startup时启动了长时间运行的任务。 无论出于何种原因,它似乎都阻塞了ApplicationStarted

根据本节https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-3.0&tabs=visual-studio#ihostedservice-interface,我删除了行services.AddSingleton<IHostedService, RunnableWrapper>();,并将CreateHostBuilder更新为以下内容:

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

现在一切正常。

我不确定为什么StartAsync中的IHostedService在默认情况下会在应用程序启动之前被调用;如果任务运行时间很长,那么它似乎会阻塞。