Dependency Injection Lifetimes
Implement or sketch code for Dependency Injection Lifetimes. Explain the logic, complexity, and pros/cons of this approach.
Answers use simple, clear English.
Quick interview answer
Logic: Singleton one instance app-wide; Scoped per request (DbContext); Transient new each resolve. Captive dependency: don't inject Scoped into Singleton.
Detailed answer
Logic: Singleton one instance app-wide; Scoped per request (DbContext); Transient new each resolve. Captive dependency: don't inject Scoped into Singleton. Complexity notes included in code section when present. Pros: Built-in container; testable via constructor injection. Cons: Wrong lifetime causes stale state or thread-safety bugs. Core: Singleton one instance app-wide; Scoped per request (DbContext); Transient new each resolve. Captive dependency: don't inject Scoped into Singleton. Real-time example: Register EF DbContext as Scoped; IEmailSender as Transient; IOptionsMonitor as Singleton. Pros: Built-in container; testable via constructor injection. Cons: Wrong lifetime causes stale state or thread-safety bugs. Common mistakes: Singleton holding mutable Scoped service; resolving Scoped from root provider. Best practices: Constructor injection only in controllers; validate scopes at startup in dev. Audience level: Junior.
Full explanation
Singleton one instance app-wide; Scoped per request (DbContext); Transient new each resolve. Captive dependency: don't inject Scoped into Singleton.
Real example & use case
Register EF DbContext as Scoped; IEmailSender as Transient; IOptionsMonitor as Singleton.
Pros & cons
Pros: Built-in container; testable via constructor injection. Cons: Wrong lifetime causes stale state or thread-safety bugs.
Code example
builder.Services.AddSingleton<ICache, MemoryCache>();
builder.Services.AddScoped<IOrderRepo, OrderRepo>();
builder.Services.AddTransient<IEmailSender, SmtpSender>();
app.MapGet("/orders/{id}", async (int id, IOrderRepo repo) =>
Results.Ok(await repo.GetAsync(id)));Practice code · csharp (view only · no execution)
builder.Services.AddSingleton<ICache, MemoryCache>();
builder.Services.AddScoped<IOrderRepo, OrderRepo>();
builder.Services.AddTransient<IEmailSender, SmtpSender>();
app.MapGet("/orders/{id}", async (int id, IOrderRepo repo) =>
Results.Ok(await repo.GetAsync(id)));Common mistakes
Singleton holding mutable Scoped service; resolving Scoped from root provider.
Best practices
Constructor injection only in controllers; validate scopes at startup in dev.
Follow-up questions
- How would you test Dependency Injection Lifetimes?
- What metrics prove Dependency Injection Lifetimes is healthy in prod?
- How does Dependency Injection Lifetimes change at 10× traffic?