Scoped or Transient Service with Hosted Service

I created an API application that allows a temperature sensor on the network. By doing this, this allows Home Assistant to access the data and control the air conditioning via Wemo Smart Outlets.

One problem that I had with this was getting the background workers to work with the database and other services in the application. What I found was that you cannot call a a Scoped or Transient service from a HostedService. Reason being is that a HostedService runs like a Singleton, and Singletons are not allowed to called scoped services.

What I ended up having to do was used a IServiceScopeFactory that will check to see if the service has been started and if not, it will create it.

This is what was done for this application that was built on .NET 5.

This is the code that I had to include in the constructor of my worker class

public InteriorLatestWorker(IServiceScopeFactory factory, ILogger<InteriorLatestWorker> logger)
{
    _logger = logger;
    _sensorService = factory.CreateScope().ServiceProvider.GetRequiredService<ISensorService>();
    _temperatureReadingService = factory.CreateScope().ServiceProvider.GetRequiredService<ITemperatureReadingService>();
}

In the Startup class, I created the hosted service and added the scoped services.

services.AddScoped<ISensorService, MockSensorService>();
services.AddScoped<ITemperatureReadingService, TemperatureReadingService>();

services.AddHostedService<InteriorLatestWorker>();

Using these, allowed my hosted service to call a scoped service. The same procedure would be done for calling a Transient service.

Posted: 2022-04-24
Author: Kenny Robinson, @almostengr