Как разрешить HostedService в контроллере - PullRequest
1 голос
/ 15 октября 2019

Я пытаюсь добавить фоновый таймер в ASP.NET Core 3.0, который периодически выполняет задачу. Google привел меня к этому , где я реализовал «Временные фоновые задачи». Тем не менее, я застрял в разрешении HostedService в контроллере. Мне нужен определенный экземпляр TimedHealthCheckService, чтобы я мог вызвать другую общедоступную функцию с именем 'GetAvailableODataUrl ()'.


В startup.cs я использую следующий код:

services.AddHostedService<TimedHealthCheckService>();

TimedHealthCheckService, очевидно, реализует IHostedService:

public class TimedHealthCheckService : IHostedService, IDisposable                  

В моем контроллере у меня есть следующий конструктор:

public HealthCheckController(ILogger<HealthCheckController> logger, IHostedService hostedService)
{
  this.logger = logger;
  this.timedHealthCheckService = hostedService as TimedHealthCheckService;
}

Однако, когда я запускаю свой WebAPI, timedHealthCheckService всегда равен нулю. Кажется, еще один IHostedService вставляется в конструктор. Проверяя hostedService, это на самом деле объект типа GenericWebHostService.

Если я изменяю конструктор контроллера на:

public HealthCheckController(ILogger<HealthCheckController> logger, TimedHealthCheckService hostedService)

Я получаю следующую ошибку:

Не удалось разрешить службу для типа «HealthCheck.Web.TimedHealthCheckService» при попытке активировать «HealthCheck.Web.Controllers.HealthCheckController».

Я также пытался services.AddSingleton<IHostedService, TimedHealthCheckService>(); с тем же результатом.

1 Ответ

1 голос
/ 16 октября 2019

Попробуйте эти две строки в файле startup.cs:

services.AddSingleton<TimedHealthCheckService>();
services.AddHostedService<TimedHealthCheckService>(provider => provider.GetService<TimedHealthCheckService>());

В первой строке выше указано, что поставщик услуг должен создать синглтон и передать его любому, кто хочет TimedHealthCheckService, как конструктор вашего контроллера. Однако поставщик услуг не знает, что синглтон на самом деле является IHostedService и что вы хотите, чтобы он вызывал StartAsync().

Вторая строка сообщает поставщику услуг, что вы хотите добавить размещенную службу, поэтомуон вызовет StartAsync(), когда приложение начнет работать. AddHostedService принимает Func<IServiceProvider,THostedService> обратный вызов. Предоставляемый нами обратный вызов выбирает синглтон TimedHealthCheckService от поставщика услуг и возвращает его обратно поставщику услуг как IHostedService. Затем поставщик услуг вызывает свою функцию StartAsync().

И в вашем контроллере:

public HealthCheckController(ILogger<HealthCheckController> logger, TimedHealthCheckService hostedService)
...