如何在控制器中解析 HostedService

Fab*_*ler 21 c# asp.net-core-3.0

我正在尝试在 ASP.NET Core 3.0 中添加一个后台计时器,它会定期执行一个任务。谷歌把我带到了这里,在那里我实现了“定时后台任务”。但是,我一直在解决控制器中的 HostedService 问题。我需要 TimedHealthCheckService 的特定实例,以便我可以调用另一个名为“GetAvailableODataUrl()”的公共函数。


startup.cs我使用以下代码:

services.AddHostedService<TimedHealthCheckService>();
Run Code Online (Sandbox Code Playgroud)

TimedHealthCheckService 显然实现了 IHostedService:

public class TimedHealthCheckService : IHostedService, IDisposable                  
Run Code Online (Sandbox Code Playgroud)

在我的控制器中,我有以下构造函数:

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

但是,当我启动 WebAPI 时,timedHealthCheckService它始终为空。似乎另一个 IHostedService 被注入到构造函数中。通过检查hostedService,它实际上是一个GenericWebHostService类型的对象。

如果我将控制器的构造函数更改为:

public HealthCheckController(ILogger<HealthCheckController> logger, TimedHealthCheckService hostedService)
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

尝试激活“HealthCheck.Web.Controllers.HealthCheckController”时无法解析“HealthCheck.Web.TimedHealthCheckService”类型的服务。

我也尝试services.AddSingleton<IHostedService, TimedHealthCheckService>();过同样的结果。

Jef*_*nie 39

在startup.cs中试试这两行:

services.AddSingleton<TimedHealthCheckService>();
services.AddHostedService<TimedHealthCheckService>(provider => provider.GetService<TimedHealthCheckService>());
Run Code Online (Sandbox Code Playgroud)

上面的第一行告诉服务提供者创建一个单例并将它提供给任何想要 a 的人TimedHealthCheckService,比如您的控制器的构造函数。但是,服务提供者不知道单例实际上是 anIHostedService并且您希望它调用StartAsync().

第二行告诉服务提供者您要添加托管服务,以便StartAsync()在应用程序开始运行时调用。 AddHostedService接受Func<IServiceProvider,THostedService>回调。我们提供的回调TimedHealthCheckService从服务提供者获取单例并将其作为IHostedService. 然后服务提供者调用它的StartAsync()函数。

在您的控制器中:

public HealthCheckController(ILogger<HealthCheckController> logger, TimedHealthCheckService hostedService)
Run Code Online (Sandbox Code Playgroud)

  • 在 asp.net core 2.1 AddHostedService 中不接受参数。有什么建议如何绕过这个吗? (3认同)
  • 伟大的!我还想知道为什么我的类构造函数被调用两次,即使我将其添加为“单例”。因此,除非我遵循此答案,否则将使用“Singleton”实例 HostedSerivce。 (2认同)