DEV Community

Cover image for Singleton Design Pattern in c#
Patrick Schadler
Patrick Schadler

Posted on • Updated on

Singleton Design Pattern in c#

Singleton Design Pattern

This post was originally published at my personal blog here.

With this post a brand-new series about Software Design Patterns starts. You will learn everything about the most used Design Patterns. The first is probably the most known. It is the Singleton Design Pattern. It is one of the twenty-three well-known - and industry standard - Gang of Four Design Pattern Collection.

All the examples, source code and unit tests are in this GitHub repository.

GitHub logo DonkeyKongJr / SingletonDesignPattern

This Repository hosts how a Singleton Design Pattern could be used.

SingletonDesignPattern

This Repository hosts how a Singleton Design Pattern could be used.

You find an up-to-date description in the related blog post here.

For any changes or updates please file a Pull Request.




What's the purpose of the Singleton Design Pattern?

In software development we often instantiate a class many times. This could be problematic. As a result you have to deal with many instances of the very same class. This introduces complexity and increases memory usage of the application.

The Singleton Design Pattern solves this specific issue. It ensures that only one instance of this class exists. Beyond that it standardizes and eases the access to that instance. To access the instance, a Singleton provides per design a static GetInstance() method. To prevent any instantiating via the new keyword you have to hide the constructor.

How does the Singleton Design Pattern looks like?

In the picture below you find the Unified Modeling Language (UML) diagram.

Singleton Singleton UML Diagram

The very basic implementation doesn't care about thread-safety. It's called BasicSingleton within the GitHub Repository.

public class BasicSingleton
{
    public string Name => Singleton;
    private static BasicSingleton instance;

    private BasicSingleton(){ }

    public static BasicSingleton GetInstance()
    {
        if(instance == default(BasicSingleton)){
                instance = new BasicSingleton();
        }

        return instance;
    }
}

How about Thread-Safety?

This implementation could lead to problems when many threads calls the GetInstance() simultaneously. For example the second thread enters the if condition while the first isn't finished yet. Thus, a second instance will be created. This behavior violates the Singleton Design Pattern definition. The ThreadSafeSingleton prevents those race conditions with locking the access to a thread at a time. This guarantees that only one instance will ever be created. Keep in mind that every time we access the Singleton we perform a lock which uses a bit more resources.

public class ThreadSafeSingleton
{
    public string Name => Singleton;
    private static ThreadSafeSingleton instance;
    private static readonly object singletonlock = new object();  

    private ThreadSafeSingleton(){ }

    public static ThreadSafeSingleton GetInstance()
    {
        lock (singletonlock)  
        {  
            if(instance == default(ThreadSafeSingleton))
            {
                instance = new ThreadSafeSingleton();
            }

            return instance;
        }          
    }
}

That’s it. Happy coding as always :).

Top comments (3)

Collapse
 
katnel20 profile image
Katie Nelson

Hey Patrick, nice post.
Have you tried using the Lazy class for thread safety?

public sealed class ThreadSafeSingleton
{
    private static readonly Lazy<ThreadSafeSingleton> lazy =
        new Lazy<ThreadSafeSingleton>(() => new ThreadSafeSingleton());

    public static ThreadSafeSingleton GetInstance() => lazy.Value;

    private ThreadSafeSingleton()
    {
    }
}

It looks to simplify things, but requires .NET 4 or higher.

Collapse
 
patzistar profile image
Patrick Schadler

Hi Katie,
no, I did not, but I will :).

Thank you for your reply.

Collapse
 
katnel20 profile image
Katie Nelson

I used it in one place so far. No issues found yet. Let me know how it works out for you.