Design Patterns & Practices  

Singleton Design Pattern in C# – Simple and Easy Explanation 🔒

Introduction

In many applications, we need only one object of a particular class. Creating multiple objects may lead to wrong results, wasted memory, or conflicts.

The Singleton Design Pattern solves this problem by ensuring that only one instance of a class exists during the application lifetime.

What Is the Singleton Pattern?

The Singleton pattern:

  • Restricts object creation to one instance

  • Provides a global access point

  • Keeps the instance thread-safe

In simple words: Create once, use everywhere.

Real-Life Examples

Here are some practical use cases:

  • Database Connection – Only one connection manager

  • Logger Class – One logger writing logs

  • Configuration Settings – Loaded once and reused

  • Printer Spooler – One controller managing print jobs

In all these cases, creating multiple objects makes no sense.

Singleton Implementation in C#

Below is a simple, thread-safe Singleton implementation using basic C# concepts.

Singleton Class

namespace DesignPattern
{
    public sealed class SingleTonClass
    {
        private static readonly object _obj = new object();
        private static SingleTonClass _instance = null;

        private int _value = 0;

        private SingleTonClass()
        {
        }

        public static SingleTonClass GetInstance()
        {
            if (_instance == null)
            {
                lock (_obj)
                {
                    if (_instance == null)
                    {
                        _instance = new SingleTonClass();
                    }
                }
            }
            return _instance;
        }

        public void IncrementValue()
        {
            _value++;
        }

        public int GetValue()
        {
            return _value;
        }
    }
}

Code Explanation (Step by Step)

sealed class SingleTonClass

  • Prevents inheritance

  • Ensures no subclass can create another instance

private static SingleTonClass _instance

  • Stores the single instance of the class

  • Static ensures it belongs to the class, not objects

private static readonly object _obj

  • Used for locking

  • Prevents multiple threads from creating multiple instances

private SingleTonClass()

  • Private constructor blocks object creation from outside

  • Forces usage of GetInstance()

GetInstance() Method

  • Acts as the global access point

  • Creates the object only once

  • Uses double-checked locking for performance and safety

_value as Instance Variable

  • Belongs to the Singleton object, not the class

  • Ensures shared state truly comes from one instance

Testing the Singleton

using System;

namespace DesignPattern
{
    public class Program
    {
        static void Main(string[] args)
        {
            var s1 = SingleTonClass.GetInstance();
            s1.IncrementValue();
            s1.IncrementValue();

            var s2 = SingleTonClass.GetInstance();
            s2.IncrementValue();
            s2.IncrementValue();

            Console.WriteLine(s2.GetValue()); // 4
            Console.WriteLine(s1.GetValue()); // 4

            if (s1 == s2)
            {
                Console.WriteLine("Both are same instance");
            }

            Console.WriteLine("Happy,Coding!");
        }
    }
}

Output Explanation

  • s1 and s2 both point to the same instance

  • _value is incremented four times in total

  • Both GetValue() calls return 4

  • Reference comparison confirms both variables refer to the same object

Why Both s1 and s2 Have the Same Value (4)

Although s1 and s2 look like different variables, they both reference the same Singleton instance.

Step-by-Step Value Flow

  • s1.IncrementValue(); → _value = 1

  • s1.IncrementValue(); → _value = 2

  • s2.IncrementValue(); → _value = 3

  • s2.IncrementValue(); → _value = 4

_value belongs to the single object. Any change through one reference is visible through the other.

That is why:

s1.GetValue(); // 4
s2.GetValue(); // 4

Why This Proves Singleton Works

  • Only one object is created

  • State (_value) is shared

  • Thread-safe creation

  • Controlled access

Advantages

  • Ensures single instance

  • Saves memory

  • Maintains consistent state

  • Easy global access

Disadvantages

  • Global state can be misused

  • Harder to unit test

  • Should not be overused

When to Use Singleton?

Use it when:

  • Exactly one object is required

  • Shared data must remain consistent

  • Object creation is expensive

Avoid it when:

  • Multiple independent instances are needed

Conclusion

The Singleton Design Pattern is a fundamental and widely used pattern in C#. This simple implementation clearly shows how one instance maintains shared state across the application.

Understanding this pattern builds a strong foundation for writing clean, efficient, and maintainable code.

Happy Coding!