.NET › Background Services
How do you safely access scoped services (like a DbContext) from within a BackgroundService, which itself is registered as a singleton?
AdvancedAnswer
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.