Skip to content

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.