ASP.NET Core › Background Tasks & Hosted Services

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

Intermediate

Answer

Since a BackgroundService instance is a singleton for the application's lifetime, you can't inject scoped services (like AppDbContext) directly into its constructor -- inject IServiceScopeFactory instead, and create a new scope for each unit of work, resolving scoped services from that scope and disposing it afterward.
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 fresh DI scope for every polling cycle, ensuring each cycle gets its own DbContext instance rather than sharing a single long-lived context across the entire application lifetime.

Common follow-ups: What exception 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?