Singleton Pattern in C#
Tags: beginners, programming, tutorial, csharp
Published: 2022-09-06 05:15:52

_Originally posted [here](https://dfordebugging.wordpress.com/2022/09/06/singleton-pattern-in-c/)_

The **Singleton** is a creational design pattern that lets us ensure that a class has only one instance while providing a global access point to this instance.

The **Singleton** pattern gives a standard means of providing a specific instance of an element all across the lifecycle of an application. Put it in another way; if the application isn't restarted, the instance remains the same.

You can find the example code of this post, on [GitHub](https://github.com/Kalkwst/DesignPatterns)

## Conceptualizing the Problem

The Singleton pattern solves two problems at the same time.

### Ensuring that a class has just a single instance

Imagine that we are implementing a new caching solution. We have a class named `CachingProvider` that contains a dictionary. In this dictionary, we will store all of our cache entries. 

After a while, we decide to create a new instance of the `CachingProvider`. Instead of receiving a fresh object, we need to get the one already created. This behaviour is impossible to implement with a regular constructor. All constructor calls **must** always return a new object by design.

### Providing a Global Access Point to the instance
While global variables can come in quite handy, they're also very unsafe since any code can potentially overwrite the contents of those variables and crash the application.

Just like global variables, the Singleton pattern lets us access some objects from anywhere in the application. However, it also protects that instance from being overwritten by any other functions.

All implementations of the Singleton pattern have these two steps in common:

- Make the default constructor private, to prevent other objects from using the `new` operator with the **Singleton** class.
- Create a static creation method that acts as a constructor. Under the hood, this method calls the private constructor to create an object and saves it in a static field. All following calls to this method return the cached object.

If the code has access to the **Singleton** class, then it's able to call Singleton's static method. So wherever that method is called, the same object is always returned.

## Structuring the Singleton Pattern

The following diagram demonstrates how the Singleton pattern works.

![Singleton High Level Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jeubumbpuph2yoc9fjgn.PNG)

1. The **Singleton** class defines exactly one instance of itself, and that instance is globally accessible.

In its base implementation, the Singleton pattern has a single participant:

- **Singleton**: The **Singleton** class declares the static `GetInstance` that returns the same instance of its class.

![Singleton Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxjej6c5g9ofinev9hey.PNG)

To demonstrate how the Singleton pattern works, we are going to think about the little bell that sits on the counter of restaurants.

The thing about that bell is that there's probably only one; the sound is used to notify the servers that the next order is at the window and needs to be taken to the tables.

Since there's only ever one bell, we can model it as a Singleton.

```csharp
namespace Singleton.NaiveSingleton
{
    /// <summary>
    /// Naive Singleton
    /// </summary>
    public sealed class Bell
    {
        private static Bell instance = null;

        // Private constructor
        private Bell() { }

        // Property to access the Instance
        public static Bell Instance
        {
            get
            {
                // Check if the Instance already exists
                if (instance == null)
                    instance = new Bell();

                return instance;
            }
        }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```

Notice that the `Bell` class has a private constructor. This is to ensure it can never be instantiated, and can only be accessed through the `Instance` property.

Let's set up the `Main` method. First, we need to define a new `bell` variable. To create an instance of the `NaiveSingleton` class, we need to call its `Instance` property.

```csharp
using Singleton.NaiveSingleton;

Bell bell = Bell.Instance;
bell.Ring();
```

And of course, the output of the above will be:

![Singleton Output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2wxbdz66dya44ht9i6j.PNG)

## Implementations of the Singleton Pattern

There are various ways to implement the **Singleton** design pattern.

### Naive Singleton (No thread safety)
```csharp
namespace Singleton.NaiveSingleton
{
    /// <summary>
    /// Naive Singleton
    /// </summary>
    public sealed class NaiveSingleton
    {
        private static NaiveSingleton instance = null;

        // Private constructor
        private NaiveSingleton() { }

        // Property to access the Instance
        public static NaiveSingleton Instance
        {
            get
            {
                // Check if the Instance already exists
                if (instance == null)
                    instance = new NaiveSingleton();

                return instance;
            }
        }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```

This implementation does not ensure thread safety as two different threads can read the `instance` variable as `null` and create different instances, thus violating the `Singleton` pattern's assurance of a single global instance.

### Simple Thread Safe Singleton
```csharp
namespace Singleton.SingleThreadSafe
{
    public sealed class SingleThreadSafe
    {
        private static SingleThreadSafe instance = null;
        private static object lockpad = new object();

        // Private Constructor
        private SingleThreadSafe() { }

        // Property to access the Instance
        public static SingleThreadSafe Instance
        {
            get
            {
                // locking the shared object
                lock (lockpad)
                {
                    if(instance == null)
                        instance = new SingleThreadSafe();

                    return instance;
                }
            }
        }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}

```

The above class provides some thread safety as the thread locks the shared object before checking for the instance. Locking the `padlock` ensures that all reads occur after the *lock acquire*, and unlocking the `padlock` ensures that all writes occur before the *lock release*.

It also ensures that only one thread will create an instance, as only one thread can acquire the lock at a time. By the time a second thread acquires the lock and enters the contested code, the first thread will have already created the instance. 

The performance of the application will suffer, since a `padlock` needs to be *acquired* and *released* **every time** a class refers to the instance.

### Double-check locking Singleton
```csharp
namespace Singleton.DoubleCheckLocking
{
    public sealed class DoubleCheckLocking
    {
        private static DoubleCheckLocking instance = null;
        private static object lockpad = new object();

        // Private Constructor
        private DoubleCheckLocking() { }

        public static DoubleCheckLocking Instance
        {
            get
            {
                // First check
                if(instance == null)
                {
                    // Locking the padlock
                    lock (lockpad)
                    {
                        if(instance == null)
                            instance = new DoubleCheckLocking();
                    }
                }

                return instance;
            }
        }
        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```

This implementation attempts thread safety without locking the `lockpad` every time the instance is called. This variant of the **Singleton** pattern has some downsides though.

We have to use this implementation as is, since any significant change of the above, is likely to impact either performance or correctness.

### No Lock Thread-Safe Singleton
```csharp
namespace Singleton.NoLockThreadSafe
{
    public sealed class NoLockThreadSafe
    {
        private static NoLockThreadSafe instance = new NoLockThreadSafe();

        // Explicit static constructor to force the C#
        // compiler not to mark the type as beforefieldinit
        static NoLockThreadSafe() { }

        private NoLockThreadSafe(){}

        public static NoLockThreadSafe Instance
        {
            get { return instance; }
        }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```

This is an extremely simple implementation of a thread-safe, lazy **Singleton**. Static constructors in C# are specified to execute only when an instance of the class is created or a static member is referenced. Static constructors also are executed only once per AppDomain.

Given that the check for the type being newly constructed is performed whatever else happens, it is faster than adding extra locking checks.

However, it's not as lazy as other implementations. In particular, if we have static members other than `Instance`, the first reference to any of them will involve creating the instance. 

### Fully Lazy Instantiation
```csharp
namespace Singleton.FullyLazyInstantiation
{
    public sealed class FullyLazyInstantiation
    {
        private FullyLazyInstantiation() { }

        public static FullyLazyInstantiation Instance { get { return Nested.Instance; } }

        private class Nested
        {
            // Explicit static constructor to force the C#
            // compiler not to mark the type as beforefieldinit
            static Nested() { }

            internal static readonly FullyLazyInstantiation Instance = new FullyLazyInstantiation();
        }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```
In this implementation, instantiation is triggered by the first reference to the static member of the nested class. This only occurs by calling `Instance`. 

This means that the implementation is fully lazy, but has all the performance benefits of the previous ones. Note that although the nested class has access to the enclosing class's private members, the reverse is not true. That doesn't raise any other problems, though, as the class itself is private.

### .NET 4's Lazy type
```csharp
namespace Singleton.DotNetLazy
{
    public sealed class DotNetLazy
    {
        private static readonly Lazy<DotNetLazy> lazy =
            new Lazy<DotNetLazy>(() => new DotNetLazy());

        public static DotNetLazy Instance => lazy.Value;

        private DotNetLazy() { }

        public void Ring()
        {
            Console.WriteLine("Ding! Order Up!");
        }
    }
}
```

If we are using .NET 4 or higher (which we probably do), we can use the [System.Lazy](https://docs.microsoft.com/en-us/dotnet/api/system.lazy-1?redirectedfrom=MSDN&view=net-6.0) type to make the laziness simple. All we need to do is to pass a delegate to the constructor which calls the **Singleton** constructor.

## Pros and Cons of Singleton Pattern

|||
|:--|:--|
|✔ We can be sure that a class has only a single instance|❌The Singleton pattern can mask bad design, for instance, when components of an application know too much about each other|
|✔ We gain a global access point to that instance|❌The pattern requires special treatment in multithreaded environments|
|✔ The singleton can be initialized only when it's requested for the first time|❌ It may be difficult to unit test the client code of the Singleton because many test frameworks rely on inheritance when producing mock objects |

## Relations with Other Patterns
- A **Facade** class can often be transformed to a **Singleton** since a single **Facade** object is sufficient in most cases.
- **Abstract Factories**, **Builders** and **Prototypes** can all be implemented as **Singletons**.

## Final Thoughts
In this article, we have discussed what is the Singleton pattern, when to use it and what are the pros and cons of using this design pattern. We then examined different implementations for the Singleton patterns and how the Singleton pattern relates to other classic design patterns.

The Singleton design pattern is helpful in many ways and is quite flexible if appropriately used. However, it's worth noting that the Singleton pattern, along with the rest of the design patterns presented by the Gang of Four, is not a panacea or a be-all-end-all solution when designing an application. Once again it's up to the engineers to consider when to use a specific pattern. After all these patterns are useful when used as a precision tool, not a sledgehammer.