Singleton

Ensures a class has only one instance and provides a global access point to it.

Context

In your application, you need an object to orchestrate a shared resource—a logging connection, an in-memory cache, global configuration—and creating multiple copies would lead to inconsistencies.

Problem
  1. Ensure that a class has exactly one instance.
  2. Provide a global access point to that instance, without resorting to loose global variables.
Solution

Make the constructor private and expose a static method that always returns the same instance, creating it lazily the first time.

#Structure

  • Private constructor.
  • Static field to hold the unique instance.
  • Static Instance method that returns it.

#Example in C#

public sealed class Logger
{
    private static readonly Lazy<Logger> _instance = new(() => new Logger());

    public static Logger Instance => _instance.Value;

    private Logger() { }

    public void Log(string message) =>
        Console.WriteLine(
quot;[{DateTime.UtcNow:O}] {message}"); } // Usage Logger.Instance.Log("Application started");

Lazy<T> solves the lazy initialization problem and is thread-safe by default (ExecutionAndPublication).

When NOT to use it
  • When you're only using it to avoid passing dependencies → you are hiding coupling. Prefer dependency injection.
  • When testing: a Singleton complicates mocks. Encapsulate it behind an interface.
  • In multi-tenant environments where you need an instance per context.
Tradeoffs
Pro Con
Ensures uniqueness Hidden global state
Lazy initialization Complicates unit tests
Clear access point Implicit coupling to the caller

#Variants

See the variants in the sidebar menu: thread-safe (manual) and enum-like readonly.

#creational #gof #instance #global