What is the difference between Transient, Scoped and Singleton?

ASP.NET Core Dependency Injection Intermediate 2–3 Yrs3–5 Yrs Conceptual 2 min read

Quick Answer

Transient: new instance on every injection — most short-lived. Scoped: one instance per request, shared within that request. Singleton: one instance for the app's entire lifetime, shared by every request and thread. Choose the shortest lifetime that still lets the service do its job, and never inject a shorter-lived service into a longer-lived one.

Transient is a fresh instance every single time it's asked for. Scoped is one instance per request — so within one HTTP call, every class that needs it gets the same object, and then it's thrown away at the end of the request. Singleton is one object for the whole application, created once and shared by every request and every thread, so it has to be thread-safe. My default is scoped for anything touching the database or request state, transient for small stateless services, and singleton only for genuinely app-wide, stateless or safely-shared things like a cache. And the golden rule: a singleton can only depend on other singletons.

AspectTransientScopedSingleton
InstancesOne per resolveOne per request/scopeOne per app
Shared across a requestNoYesYes
Shared across requestsNoNoYes
Thread-safety neededRarelyNo (single request)Yes
Typical useSmall stateless helpersDbContext, unit of work, request contextCaches, config, clock, HttpClientFactory internals
May safely depend onTransient, Scoped, SingletonScoped, Singleton (and Transient)Singleton only

Practical notes:

  • A transient service resolved by a scoped service effectively lives as long as that scope (it is held by the scoped object).
  • A transient IDisposable captured by a singleton is never disposed until app shutdown — a subtle leak.
  • Registering the same type as scoped in one place and singleton in another leads to confusing behaviour; pick one.

C# — what each lifetime returns
// Two injections in the SAME request:
// Transient  -> a1 != a2
// Scoped     -> b1 == b2
// Singleton  -> c1 == c2

// The SAME registration across TWO requests:
// Transient  -> different
// Scoped     -> different (scope ended)
// Singleton  -> identical

Practise the whole thread the way an interviewer walks it — each question builds on the last.

  1. What is Dependency Injection in ASP.NET Core?
  2. What is loose coupling?
  3. What is Inversion of Control (IoC)?
  4. What are service lifetimes in ASP.NET Core?
  5. What is the difference between Transient, Scoped and Singleton?You are here
  6. Why is DbContext registered as Scoped?
  7. What is a captive dependency?