ASP.NET Core  

AddTransient vs AddScoped vs AddSingleton in ASP.NET Core

Introduction

In ASP.NET Core, Dependency Injection (DI) is a built-in feature that helps manage object creation and lifetime. When you register services in the DI container, you often see three common methods: AddTransient, AddScoped, and AddSingleton.

Understanding the difference between AddTransient vs AddScoped vs AddSingleton is very important for building scalable, high-performance, and bug-free applications. Choosing the wrong lifetime can lead to memory issues, unexpected behavior, or performance problems.

In this article, we will explain each lifetime in simple words, compare them clearly, and show real-world examples so you can confidently decide which one to use.

What is Dependency Injection in ASP.NET Core?

Dependency Injection is a design pattern used to achieve loose coupling between classes.

Instead of creating objects manually, the framework provides them when needed.

Example:

public interface IMessageService
{
    void Send(string message);
}

public class EmailService : IMessageService
{
    public void Send(string message)
    {
        Console.WriteLine($"Email Sent: {message}");
    }
}

Registering in DI container:

builder.Services.AddTransient<IMessageService, EmailService>();

What is AddTransient?

AddTransient creates a new instance of a service every time it is requested.

Key Points of AddTransient

  • New object is created every time

  • Lightweight and short-lived

  • No shared state

  • Best for stateless services

Example of AddTransient

builder.Services.AddTransient<IMessageService, EmailService>();

If this service is injected into multiple places, each injection gets a new instance.

When to Use AddTransient

  • Stateless services

  • Lightweight operations

  • Services with no shared data

What is AddScoped?

AddScoped creates one instance per request.

In web applications, a "request" means a single HTTP request.

Key Points of AddScoped

  • One instance per request

  • Shared within the same request

  • New instance for each new request

Example of AddScoped

builder.Services.AddScoped<IMessageService, EmailService>();

All components within the same request share the same instance.

When to Use AddScoped

  • Database contexts (like DbContext)

  • Request-based operations

  • Services that need to share data within a request

What is AddSingleton?

AddSingleton creates only one instance for the entire application lifetime.

Key Points of AddSingleton

  • Single instance for entire app

  • Created once and reused

  • Shared across all requests

  • Must be thread-safe

Example of AddSingleton

builder.Services.AddSingleton<IMessageService, EmailService>();

All users and requests share the same instance.

When to Use AddSingleton

  • Configuration services

  • Caching services

  • Logging services

  • Expensive object creation

Difference Between AddTransient, AddScoped, and AddSingleton

FeatureAddTransientAddScopedAddSingleton
LifetimeNew every timePer requestEntire application
Instance SharingNoWithin requestAcross application
Memory UsageLow per instanceModerateLowest (single instance)
Thread Safety RequiredNoNoYes
PerformanceFast creationBalancedBest for reuse

Visual Understanding

  • AddTransient → Always new instance

  • AddScoped → Same instance per request

  • AddSingleton → Same instance for entire app

Real-World Example

Imagine an e-commerce application:

  • AddTransient → Email sender service (no shared data)

  • AddScoped → Shopping cart service (per user request)

  • AddSingleton → Configuration service (shared globally)

Common Mistakes Developers Make

  • Using Singleton for services that depend on Scoped services

  • Not making Singleton services thread-safe

  • Overusing Transient leading to too many object creations

  • Misunderstanding request scope in APIs

Important Rule (Very Important)

Never inject a Scoped service into a Singleton.

This can cause runtime errors because Singleton lives longer than Scoped.

Best Practices

  • Use AddTransient for lightweight, stateless services

  • Use AddScoped for request-based logic

  • Use AddSingleton for shared, expensive services

  • Always consider thread safety

Advanced Tip

If you are unsure which lifetime to choose:

  • Start with Scoped for most services in web apps

  • Optimize later based on performance needs

Summary

Understanding AddTransient vs AddScoped vs AddSingleton is essential for effective Dependency Injection in ASP.NET Core. Transient creates a new instance every time, Scoped creates one per request, and Singleton creates one for the entire application. Choosing the correct lifetime helps improve performance, maintainability, and scalability of your application.