Lifetime: Singleton
Learn single-instance services with Singleton lifetime.
Singleton lifetime
The AddSingleton<T>() registration produces a single instance for the whole application. When you resolve the same service multiple times, you get the same instance every time. This suits services that hold shared state.
Singleton instances live as long as the container. They must therefore be thread-safe. Configuration, cache and global state services are usually registered as singleton.
Thread safety
Singleton instances must be safe for concurrent access. The container produces the instance lazily once; threads accessing the same instance concurrently can race. State changes are therefore protected with lock or concurrent collections.
For read-only configuration services, extra synchronization may be unnecessary. But any Singleton that mutates state, such as a counter service, requires locking.
Exercise Singleton: verify the same instance
In Main, create the container with var services = new ServiceCollection();. Register Counter as singleton with services.AddSingleton<Counter>();. Build the provider with var provider = services.BuildServiceProvider();. Resolve twice with var c1 = provider.GetRequiredService<Counter>(); and var c2 = provider.GetRequiredService<Counter>();. Set c1.Count = 5; and print Console.WriteLine(c2.Count);.
Show example solution
var services = new ServiceCollection(); services.AddSingleton<Counter>(); var provider = services.BuildServiceProvider(); var c1 = provider.GetRequiredService<Counter>(); var c2 = provider.GetRequiredService<Counter>(); c1.Count = 5; Console.WriteLine(c2.Count);
Example solution:
using System;
using Microsoft.Extensions.DependencyInjection;
class Counter
{
public int Count { get; set; }
}
class Program
{
static void Main()
{
var services = new ServiceCollection();
services.AddSingleton<Counter>();
var provider = services.BuildServiceProvider();
var c1 = provider.GetRequiredService<Counter>();
var c2 = provider.GetRequiredService<Counter>();
c1.Count = 5;
Console.WriteLine(c2.Count);
}
}
Test yourself
-
When is AddSingleton used?
- When a new instance is needed each request
- When a separate instance is needed per scope
- When a single instance is shared for the whole app
- Only for debugging
Show answer
When a single instance is shared for the whole app — Correct. AddSingleton is used when one instance is shared for the whole app.
-
Complete the Singleton registration
services.Add____<Counter, Counter>();Show answer
services.AddSingleton<Counter, Counter>(); -
Match the lifetime to its behavior
- Singleton
- Single instance
- Scoped
- Per scope
- Transient
- New each time
- AddSingleton
- Registration method