C#  

C# Singleton Pattern: One Instance to Rule Them All

What is the Singleton Pattern?

The Singleton Design Pattern is a creational pattern that ensures only one instance of a class is created and provides a global access point to that instance.

In simple terms, imagine you have a class that should only ever have one object (like a single log manager, configuration handler, or shared resource). The Singleton pattern helps you do exactly that.

When to Use Singleton Pattern?

Use Singleton when,

  • You need to limit a class to a single instance.
  • You want to control access to shared resources like file handlers, database connections, logging services, etc.
  • You want a centralized object that's reused throughout the application.

Basic Structure of Singleton Pattern

Key Points

  • Private constructor to prevent external instantiation.
  • Static variable to hold the single instance.
  • Public static method or property to provide access.

Basic Example

public sealed class Singleton
{
    private static Singleton instance = null;

    // Private constructor to prevent object creation
    private Singleton()
    {
        Console.WriteLine("Singleton instance created");
    }

    // Public method to get the instance
    public static Singleton GetInstance()
    {
        if (instance == null)
        {
            instance = new Singleton();
        }
        return instance;
    }
}

Thread-Safe Singleton

In multi-threaded applications, the basic version might create multiple instances. So we make it thread-safe:

Using Lock

public sealed class Singleton
{
    private static Singleton instance = null;
    private static readonly object lockObj = new object();
    private Singleton() { }
    public static Singleton GetInstance()
    {
        lock (lockObj)
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

Best Practice: Lazy Initialization

C# also provides an easy way using Lazy<T>.

public sealed class Singleton
{
    private static readonly Lazy<Singleton> instance = 
        new Lazy<Singleton>(() => new Singleton());
    private Singleton() { }
    public static Singleton Instance => instance.Value;
}

Eager vs Lazy Loading
 

Approach Description
Eager The instance is created at application start. Good for performance-critical cases.
Lazy The instance is created when it's needed. Saves memory and start-up time.


Drawbacks of Singleton

  • Can make unit testing difficult (tight coupling).
  • It might be overused when a simple static class would do.
  • Risk of hidden dependencies across the app.

Real-Time Use Cases

  • Logger
  • Configuration settings
  • Database connection manager
  • Caching mechanism

Summary

  • Singleton ensures one instance only.
  • It’s helpful for managing shared resources.
  • Make it thread-safe for multi-threaded apps.
  • Use lazy loading for better performance when n