Singleton Pattern: Global Instance Management
Singleton Pattern: Global Instance Management
The Singleton Pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to it.
ποΈ The Problem
Suppose you have a Configuration Manager that reads settings from a file. You donβt want to create a new instance of this manager every time you need a setting, as that would be a waste of memory and CPU. You need exactly one instance shared across the entire application.
π The .NET Implementation
In .NET, the most thread-safe way to implement a Singleton is using Lazy<T>.
1. The Singleton Class
public sealed class ConfigurationManager
{
// Lazy ensures thread-safe and lazy initialization
private static readonly Lazy<ConfigurationManager> _instance =
new Lazy<ConfigurationManager>(() => new ConfigurationManager());
// Public access point
public static ConfigurationManager Instance => _instance.Value;
// Private constructor! No one else can create an instance.
private ConfigurationManager()
{
Console.WriteLine("[SINGLETON]: Initializing Configuration Manager...");
}
public string GetSetting(string key) => $"Value for {key}";
}π οΈ Real-World Usage (Client)
// Both variables point to the same object!
var manager1 = ConfigurationManager.Instance;
var manager2 = ConfigurationManager.Instance;
// ReferenceEquals returns true
Console.WriteLine(ReferenceEquals(manager1, manager2));
var value = manager1.GetSetting("ApiKey");π‘ Why use Singleton?
- Global State: Perfect for configuration, logging, or caching.
- Controlled Access: You can control the instantiation of the object (e.g., only create it when first needed).
- Cons: Be careful! Singletons can make unit testing harder because they introduce global state. In modern .NET Core, we often use Dependency Injection (Singleton lifetime) instead of a manual Singleton pattern.