Getting to know Singleton pattern in C#


7 years ago -  
C#Design Patterns

This pattern helps us to ensure a class has only one instance. The term comes from the mathematical concept of a singleton:

In mathematics, a singleton, also known as a unit set,[1] is a set with exactly one element. For example, the set {0} is a singleton.

Eventually we must have a class that only gives us a single instance:

var sigleInstance = MySingletonClass.GetInstance();

As you can see the only way to access the instance is by calling a public static method called GetInstance(), the single object instance under consideration is created only for the first time it is requested. suppose the following class:

public class MySingletonClass
{
    public MySingletonClass()
    {

    }
}

Now I want to make this class singleton, So the first step is to ensure that no one can instantiate our class for doing so we must make the constrauctor private:

public class MySingletonClass
{
    private MySingletonClass()
    {

    }
}

Now whenever you want to create a new instance of MySingletonClass using new keyword, Visual Studio gives you this error:

But we can still instantiate it from within the class. So next step is to create a new variable of type MySingletonClass inside the class, this class is going to be the only instance of the class:

public class MySingletonClass
{
	private static MySingletonClass _instance;

	private MySingletonClass() { }
}

So we are getting close to implementing the pattern. Now we need a way to get access the single instance. So we need a method like this:

public static MySingletonClass GetInstance()
{
	if (_instance == null)
	{
		_instance = new MySingletonClass();
	}
	return _instance;
}

This method instantiates MySingletonClass if an instance doesn’t already exist, otherwise it return the existing instance. To demonstrate the object lifetime we can print value of GetHashCode() fo these objects:

var mySingleInstance   = MySingletonClass.GetInstance();
var mySingleInstance_2 = MySingletonClass.GetInstance();
var mySingleInstance_3 = MySingletonClass.GetInstance();
var mySingleInstance_4 = MySingletonClass.GetInstance();

Console.WriteLine($"obj1: {mySingleInstance.GetHashCode()}");
Console.WriteLine($"obj2: {mySingleInstance_2.GetHashCode()} ");
Console.WriteLine($"obj3: {mySingleInstance_3.GetHashCode()} ");
Console.WriteLine($"obj4: {mySingleInstance_4.GetHashCode()} ");

As you can see all of the objects are the same and share the same instance. The problem with this implementation is that, it’s not thread-safe; it means that if seperate threads of execution access the _instance at the same time, more that one instance of the MySingletonClass object may be created. One of the solution is by using .NET 4’s Lazy<T> type:

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

    private MySingletonClass() { }

    public static MySingletonClass GetInstance()
    {
    	return _instance.Value;
    }

}