.NET › Background Services

How do you safely access scoped services (like a DbContext) from within a BackgroundService, which itself is registered as a singleton?

Advanced

Answer

Since BackgroundService instances are singletons for the app's lifetime, you cannot inject scoped services directly into the constructor -- instead, inject IServiceScopeFactory (or IServiceProvider) and create a new scope for each unit of work, resolving scoped services from that scope and disposing it afterward, mirroring how ASP.NET Core creates a fresh scope per HTTP request.
public class OrderProcessor : BackgroundService {
    private readonly IServiceScopeFactory _scopeFactory;
    public OrderProcessor(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
        while (!stoppingToken.IsCancellationRequested) {
            using var scope = _scopeFactory.CreateScope();
            var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
            await ProcessPendingOrdersAsync(db);
            await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
        }
    }
}
Real-world example A background order-processing service creates a new DI scope for every polling cycle, ensuring each cycle gets a fresh DbContext instance rather than sharing one long-lived context across the entire application lifetime, which would cause stale data and tracking issues.

Common follow-ups: What error occurs if you try injecting a scoped DbContext directly into a BackgroundService constructor?;How often should you create a new scope -- per iteration or per item processed?