Lifetimes describe reuse and ownership
Transient services are created each time they are requested. Scoped services are reused within a scope, commonly one HTTP request. Singleton services are shared for the lifetime of the host. Choose a lifetime based on the state and dependencies the service owns.
Avoid captive scoped dependencies
A singleton cannot safely hold a scoped DbContext: the context would outlive its intended scope and could be used concurrently. Resolve scoped work inside an explicit scope, such as a hosted worker creating a scope for each batch.
await using var scope = scopeFactory.CreateAsyncScope();
var handler = scope.ServiceProvider.GetRequiredService<IImportBatchHandler>();
await handler.ProcessAsync(batchId, stoppingToken);
DbContext is scoped for a reason
EF Core DbContext tracks changes and is not thread-safe. Do not share one context across concurrent tasks. Keep one request or unit-of-work operation within a scope, and do not run overlapping database calls on the same context.
Interview takeaway
Name the lifetime, then explain who creates the scope, how long mutable state lives, and whether any dependency is shared across concurrent operations.