Singleton
Singleton ensures only one instance of a class exists. Useful when you need exactly one shared resource like a connection pool, logger, etc. Most times, passing shared objects through constructors is clearer, works, and easily testable.
Sample
public class DatabaseConnection
{
public static DatabaseConnection Instance
{
get
{
_instance ??= new DatabaseConnection();
return _instance;
}
}
private static DatabaseConnection? _instance;
private DatabaseConnection() {}
}
… with usage:
var db = DatabaseConnection.Instance;
var users = db.Query("SELECT * FROM users");
In multi-threaded scenarios, C# offers Lazy<T> w/ options for ensuring thread
safety, e.g., LazyThreadSafetyMode.ExecutionAndPublication ensures that only
a single thread can initialize a Lazy<T> instance, and set (publish) the value
of the Lazy<T> instance. T is initialized the first time Lazy<T>.Value is
accessed.
DI Containers
Dependency injection frameworks abstract away the complexity of creating and testing singletons.
For example, .NET allows us to create class instances with different lifetimes:
// A Foo instance is created each time it's requested from the DI container.
services.AddTransient<IFoo, Foo>();
// Given a scope, e.g., the one created on a client/server connection, Bar is
// only created once within that scope.
services.AddScoped<IBar, Bar>();
// Created once, and the same instance is used on every subsequent request.
services.AddSingleton<IBaz, Baz>();
… with some caveats, e.g., do not resolve a service from another service with a longer lifetime (e.g., a singleton resolving a scoped service).
References
- Design Patterns | Hello Interview Low Level Design. www.hellointerview.com . Accessed Sep 16, 2026.
- Lazy<T> Class (System) | Microsoft Learn. learn.microsoft.com . Accessed Sep 21, 2026.
- LazyThreadSafetyMode Enum (System.Threading) | Microsoft Learn. learn.microsoft.com . Accessed Sep 21, 2026.
- Service lifetimes (dependency injection) - .NET | Microsoft Learn. learn.microsoft.com . Accessed Sep 21, 2026.