Singleton Pattern (C#) β€” Interview Notes

πŸ” Flashcards (Top)

Q: What is the Singleton pattern?
A: Ensures a class has exactly one instance and provides controlled global access to it.


Q: What are the 3 mandatory components of a Singleton?
A: Private constructor, static instance holder, public static access point.


Q: Why is a naive Singleton not thread-safe?
A: Multiple threads can pass the null check and create multiple instances.


Q: Best Singleton implementation in C#?
A: Lazy<T> β€” thread-safe, lazy, and CLR-managed.


Q: Is Singleton the same as a static class?
A: No. Singleton supports interfaces, DI, and lazy initialization.


Q: Why is Singleton often criticized?
A: Hidden global state, tight coupling, poor testability.


🧠 Core Idea

Singleton controls object creation, not just access.
Exactly one instance exists for the application lifetime.


βœ… When Singleton Makes Sense

  • Application configuration
  • Logging / metrics
  • Cache managers
  • Expensive, shared resources

❌ When NOT to Use Singleton

  • Business logic or services
  • Objects with mutable shared state
  • Code that must be unit-tested or mocked
  • Modern apps using DI containers

🧩 Naive Singleton (NOT Thread-Safe)

public class Singleton
{
    private static Singleton _instance;
 
    private Singleton() { }
 
    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
        }
    }
}
 
 
βΈ»
 
⚠️ Thread-Safe (Double-Checked Locking)
 
public class Singleton
{
    private static volatile Singleton _instance;
    private static readonly object _lock = new object();
 
    private Singleton() { }
 
    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (_lock)
                {
                    if (_instance == null)
                        _instance = new Singleton();
                }
            }
            return _instance;
        }
    }
}
 
 
βΈ»
 
⭐ Best Practice (Recommended)
 
Lazy<T> Singleton
 
public class Singleton
{
    private static readonly Lazy<Singleton> _instance =
        new Lazy<Singleton>(() => new Singleton());
 
    private Singleton() { }
 
    public static Singleton Instance => _instance.Value;
}
 
Why this is best
	β€’	Thread-safe by default
	β€’	Lazy initialization
	β€’	No manual locks
	β€’	CLR guarantees correctness
 
βΈ»
 
βš™οΈ Singleton vs Static vs DI
 
Aspect	Singleton	Static	Dependency Injection
Instance control	Class	CLR	Container
Lazy init	Yes	No	Yes
Interfaces	Yes	No	Yes
Testability	Poor	None	Excellent
Enterprise usage	Limited	Rare	Preferred
 
 
βΈ»
 
🏒 Enterprise Reality (C#)
 
Good
	β€’	Immutable configuration
	β€’	Logging wrappers
	β€’	Metrics collectors
 
Bad
	β€’	Service locator (SomeService.Instance)
	β€’	Shared mutable state
	β€’	Replacement for DI
 
Modern approach
 
services.AddSingleton<IService, Service>();
 
 
βΈ»
 
🎯 Interview One-Liner
 
Singleton guarantees a single instance, but in modern C# systems, dependency injection is usually a safer and more testable way to manage singleton lifetimes.
 
---