October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk4 min

Singleton, Scoped, or Transient? Choose the Right .NET DI Lifetime

A .NET DI lifetime sets an instance’s reuse and disposal boundary. Compare transient, scoped, and singleton, and learn how to keep scoped work out of long-lived services.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In .NET dependency injection, choose a service lifetime by asking who should share the instance, how long it should live, and who should dispose it. A singleton that holds request-specific state can create the familiar shared-state bug: data or resources persist beyond the boundary where you expected them to end. That is an analogy, not a claim that every lifetime mistake has the same cause.

What a dependency injection lifetime controls

A lifetime is the container’s rule for reusing an instance and owning its disposal. In Microsoft’s built-in .NET dependency injection, the three choices are transient, scoped, and singleton. Their exact behavior can differ in other containers, so check the framework’s own rules before applying these details elsewhere. Microsoft Learn: service lifetimes

As an Amazon Associate I earn from qualifying purchases.

How the three lifetimes differ

Lifetime Reuse boundary State and thread-safety Disposal boundary Typical fit
Transient A new instance is created each time the service is requested from the container. Separate resolutions do not share the instance’s state. If a singleton receives and retains a transient, however, that instance is retained by the singleton; consider how it is used and whether concurrent access requires thread safety. The container disposes container-created instances according to its ownership and scope rules; do not dispose a container-owned dependency yourself. Lightweight services that do not need shared state or a scope-wide instance.
Scoped One instance is reused within a scope. In request-processing ASP.NET Core apps, the scope is commonly one client request. State can be shared by code resolving the service inside that scope, but should not be treated as application-wide state. Disposed when its scope ends. In a web request, that is ordinarily the end of the request. Work tied to a request or another bounded operation. AddDbContext registers DbContext as scoped by default.
Singleton The same instance is used for subsequent requests from the service provider, for that provider’s lifetime. State is shared among callers. Singleton services must be thread-safe. Lives until the service provider is disposed; it can retain its object graph and resources until then. State-free shared services or deliberately shared, thread-safe state whose lifetime is application-wide.

These are reuse rules, not a speed ranking. Repeated construction may cost something, but selecting a lifetime primarily means selecting a state-sharing and disposal boundary. Microsoft’s .NET dependency injection overview describes the built-in container’s role in managing services.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why a lifetime mismatch resembles a familiar bug

Imagine a service designed to hold information for one request. If a singleton captures that service, the singleton may keep using the same request-specific object as later requests arrive. The result can resemble caching user data in a global object: one caller’s state may affect another, resources may be stale, and objects may remain in memory longer than intended. The root cause here is lifetime capture; shared mutable state and use beyond an owner’s boundary are useful analogies, not interchangeable diagnoses.

Microsoft calls a longer-lived service holding a shorter-lived one a “captive dependency.” Its dependency injection guidelines define the term as a misconfiguration in which “a longer-lived service holds a shorter-lived service captive.” A scoped dependency injected into a singleton is a direct example. The singleton outlives the scope for which the dependency was designed, so request-specific state may persist across requests. A scoped service resolved from the root provider can also effectively become singleton-like: it remains alive until that root provider is disposed.

How to choose a lifetime

  • Choose transient when each resolution should receive a fresh instance and the service does not need to share state across resolutions.
  • Choose scoped when the same instance should serve one request or another explicitly bounded unit of work, then be released when that scope ends.
  • Choose singleton only when sharing one instance for the service-provider lifetime is intentional. Make it thread-safe and avoid retaining request-specific state or dependencies.

Do not make a service singleton just to reduce construction, or transient just because it seems safest. A transient captured by a singleton is no longer effectively short-lived in use. Decide based on the intended sharing boundary, state, and disposal behavior.

How to use scoped work from a singleton or background service

A singleton or hosted background service sometimes needs to perform an operation using scoped dependencies. Create a scope for that operation, resolve the scoped service from the scope, finish the work, and let the scope dispose its services. Do not store the scoped service on the singleton for reuse.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Inject IServiceScopeFactory into the singleton or hosted service.
  2. For each bounded operation, create a scope with CreateScope().
  3. Resolve the scoped service from that scope’s ServiceProvider, use it only within the operation, then dispose the scope.

This makes the operation, rather than the application-wide singleton, the owner of the scoped instance. Microsoft’s service-lifetime guidance describes creating a scope when a singleton needs scoped work.

Where scoped dependencies belong in ASP.NET Core middleware

Conventional middleware is long-lived. A scoped dependency therefore should not be captured through its constructor. Put that dependency in the middleware’s Invoke or InvokeAsync method, where it can be supplied within the request scope, or use factory-based middleware. See Microsoft’s ASP.NET Core dependency injection guidance for middleware-specific details.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How to catch and diagnose lifetime mistakes

Enable scope validation in development so the built-in provider can catch common cases, such as resolving a scoped service from the root provider or injecting one into a singleton. Validation is a safeguard, not a substitute for understanding who owns an instance and how long it should live.

  • Ask who shares it: one resolution, one scope, or the whole service-provider lifetime?
  • Check what it retains: a singleton must not hold request-specific scoped state beyond the request.
  • Check who ends its life: allow the container and scope to dispose instances they created; do not dispose a container-owned dependency yourself.
  • Look for boundary symptoms: state appearing across requests, stale scoped resources, or memory retained until provider shutdown can point to an instance living longer than intended.

Microsoft’s DI guidelines cover disposal and other container-use recommendations. If you need a broader treatment of DI design in C# and .NET, Manning’s Dependency Injection Principles, Practices, and Patterns explores principles, patterns, and anti-patterns.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.