Mid-level (2-5 years)C#

What are transient, scoped and singleton service lifetimes in ASP.NET Core dependency injection?

Quick answer

Transient services are created every time they are requested, scoped services are created once per HTTP request, and singleton services are created once and shared for the life of the application.

Register services in Program.cs with AddTransient, AddScoped or AddSingleton. Use transient for lightweight, stateless services, scoped for things tied to a request such as an Entity Framework DbContext, and singleton for shared, thread-safe objects such as caches and configuration.

The classic bug is a captive dependency: a singleton that depends on a scoped service keeps that one instance alive forever, so a DbContext ends up shared across requests and threads. ASP.NET Core can detect this in development with scope validation. Singletons must also be thread-safe because many requests use them at once.

builder.Services.AddTransient<IEmailBuilder, EmailBuilder>();
builder.Services.AddScoped<AppDbContext>();
builder.Services.AddSingleton<IMemoryCache, MemoryCache>();

public class OrdersController(AppDbContext db, IEmailBuilder email) : ControllerBase { }

Key points

  • Transient: new every time. Scoped: per request. Singleton: one for the app
  • Never inject a scoped service into a singleton
  • Singletons must be thread-safe

Questions interviewers ask next

  • What is the middleware pipeline in ASP.NET Core?
  • What is the difference between AddScoped and AddDbContext?