asp.net-corebackgroundworker

Background tasks with .NET CORE Lifetime and DI injection


I want to use background tasks in asp.net core. I found helpful documentation https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio

I wonder why their lifetime apparently is scoped: Hosted service that activates a scoped service. The scoped service can use dependency injection (DI). What is the scope in this context?

For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped. In apps that process requests, scoped services are disposed of at the end of the request.

While I do understand what that means for e.g a standard http get request to an API, I do not understand the meaning of being a background worker. Imho it would make more sense to have a singleton backgroundworker. I certainly do not want to have multiple instances running at a time in my application.

Another thing is DI in background workers which apparently differs from standard services: To use scoped services within a BackgroundService, create a scope. No scope is created for a hosted service by default.

I cannot confirm that:

    services.AddHostedService(x => new DataPersister(x.GetRequiredService<IAsyncDocumentSession>(), x.GetRequiredService<ILogger>()));

seems to work just fine.


Solution

  • You have to read the sentence “Hosted service that activates a scoped service” within its full context:

    This article provides three hosted service examples:

    • Background task that runs on a timer.
    • Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
    • Queued background tasks that run sequentially.

    (from “Background tasks with hosted services”, emphasis mine)

    So it is not the case that hosted services have a scoped lifetime. All hosted services added using AddHostedService() are actually added with a singleton lifetime, ensuring that there will only ever be a single instance of it.

    What the article refers to is the situation when you need to consume a scoped service, like a database connection, within a hosted service. Since you cannot inject scoped dependencies into a singleton service, you will need a different solution there. And the solution usually involves having the singleton service (the hosted service in this case) create a service scope itself from which it can then retrieve the scoped dependency.

    I went into more details about the service scopes in this recent answer to a similar question if you are interested.