Singleton Design pattern

In this tutorial we will cover following topics
  1. Implementation of Singleton design pattern.
  2. Why Singleton class is a static class.
  3. Multi-threading safety in Singleton.
  4. Lazy loading and Eager loading.
  5. Difference b/w Static class and singleton class.


This is very popular creational design patterns which restrict us to have an instance of a class.
Note: A singleton class can't have a public constructor and it has to be sealed. The entry point to get the singleton instance would be a static method or a static property. 



Singleton design pattern is implemented when we need one object of a class is initiated and that object is used across the application like the following image



In above diagram we will see different objects trying to invoke an object instantiated as singleton. This single instance of the object is responsible to invoke underneath methods or events.
We will understand this Singleton design pattern with an example
1.   Go to visual studio and select a console application and give name as  “SingletonApplication
2.   Add a class to this application and give this class name as “Singleton” and write the following code to this class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{

    // Sealed ensures to restricted in the derived class

    public  class Singleton
    {
        private static int counter = 0;
 
        public Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}


This in this we created a function to print and a static variable to check that how many instance is creating or this class.

Now call “PrintDetails” function from the “Programe.cs” class like following
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * Assuming Singleton is created from employee class
             * we refer to the GetInstance property from the Singleton class
             */
            Singleton fromEmployee = new Singleton();
            fromEmployee.PrintDetails("From Employee");
            /*
             * Assuming Singleton is created from student class
             * we refer to the GetInstance property from the Singleton class
             */
            Singleton fromStudent = new Singleton();
            fromStudent.PrintDetails("From Student");

            Console.ReadLine();
        }
    }
}


Now when we run this application and see


Above image we can see that its counter value is incrementing as much time we are calling to this class it means it’s creating the instance 2 time for “singleton” class which is not the rule of singleton design pattern.
Now make some changes in “singleton.cs” class and” program.cs” class.
Write the following code to Singleton.cs class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
   
      // Sealed ensures to restricted in the derived class
    
    public sealed class Singleton
    {
        private static int counter = 0;

        /*
         * Private property initilized with null
         * ensures that only one instance of the object is created
         * based on the null condition
         */
        private static Singleton instance = null;

        /*
         * public property is used to return only one instance of the class
         * leveraging on the private property
         */
        public static Singleton GetInstance
        {
            get
            {
                if (instance == null)
                    instance = new Singleton();
                return instance;
            }
        }
        /*
         * Private constructor ensures that object is not
         * instantiated other than with in the class itself
         */
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}


Program.cs class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
    class Program
    {
         static void Main(string[] args)
        {
            /*
             * Assuming Singleton is created from employee class
             * we refer to the GetInstance property from the Singleton class
             */
            Singleton fromEmployee = Singleton.GetInstance;
            fromEmployee.PrintDetails("From Employee");
            /*
             * Assuming Singleton is created from student class
             * we refer to the GetInstance property from the Singleton class
             */
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");

            Console.ReadLine();
        }
    }
}


Run your application and see the output

Now we can see that counter value is not incrementing as much we create the object for that class and this example follow the rule of singleton design pattern.
Why singleton class is a sealed class
This can be a question arise in our mind that when we have private constructor in singleton class then what is the need to make that class as Sealed class.
We will understand this with an example
Lets create a class name “DerivedSingleton” and Inherit the singleton class ,it will give compile time error that Singleton is inaccessible due to its protection level, Because singleton is private class.

So now move this derived class “DerivedSingleton” into the singleton class like following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{

    public class Singleton
    {
        private static int counter = 0;
        private static object obj = new object();
        /*
        * Private constructor ensures that object is not
        * instantiated other than with in the class itself
        */
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        private static Singleton instance = null;
        /*
         * public property is used to return only one instance of the class
         * leveraging on the private property
         */
        public static Singleton GetInstance
        {
            get
            {
                if (instance == null)
                    instance = new Singleton();
                return instance;
            }
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
        /*
         * By removing sealed keyword we can inherit the singleton and instantiate multiple objects
         * This violates singleton design principles.
         */
        public class DerivedSingleton : Singleton
        {
        }
    }
}


We have remove sealed keyword from the class that why we are able to inherit .
Write the following code in program class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
            * Assuming Singleton is created from student class
            * we refer to the GetInstance property from the Singleton class
            */
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");
            /*
            * Assuming Singleton is created from employee class
            * we refer to the GetInstance property from the Singleton class
            */
            Singleton fromEmployee = Singleton.GetInstance;
            fromEmployee.PrintDetails("From Employee");

            Console.WriteLine("-------------------------------------");
            /*
             * Instantiating singleton from a derived class. This violates singleton pattern principles.
             */
            Singleton.DerivedSingleton derivedObj = new Singleton.DerivedSingleton();
            derivedObj.PrintDetails("From Derived");

            Console.ReadLine();
        }
    }
}


Now run your application and see the output, you will see that counter value is incremented, that proving that we are able to create multiple instances of the singleton using the nested derived class



This violates the principle of singleton.  Let’s go back to the Singleton and make the class as sealed and remove the DeriviedSingleton class.
Multithread Safety in Singleton
Lazy Initialization The lazy initialization of an object improves the performance and avoids unnecessary computation till the point the object is accessed. Further, it reduces the memory footprint during the startup of the program. Reducing the memory print will help faster loading of the application. 
Lazy Initialization in our example : GetInstance Property is responsible for the Singleton Instance creation. Singleton object is not instantiated until and unless GetInstance is invoked. Hence, there is a delay in instance creation till the GetInstance is accessed. This Delay in Instance creation is called Lazy Initialization.
Basically Lazy initialization work fine in single credential environment. In other case suppose that if multithreading are invoking same getinstance property at same instance of time then their chance that it create multiple instance for this property.
Lets understand this with an example
Go to the Program class and write the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
    class Program
    {
        static void Main(string[] args)
        {

            System.Threading.Tasks.Parallel.Invoke(
                () => PrintStudentdetails(),
                () => PrintEmployeeDetails()
                );
            Console.ReadLine();
        }

        private static void PrintEmployeeDetails()
        {
            /*
             * Assuming Singleton is created from employee class
             * we refer to the GetInstance property from the Singleton class
             */
            Singleton fromEmployee = Singleton.GetInstance;
            fromEmployee.PrintDetails("From Employee");
        }

        private static void PrintStudentdetails()
        {
            /*
                         * Assuming Singleton is created from student class
                         * we refer to the GetInstance property from the Singleton class
                         */
            Singleton fromStudent = Singleton.GetInstance;
            fromStudent.PrintDetails("From Student");

        }

    }

}


Here System.Threading.Tasks.Parallel.Invoke is a static method which is given by the Microsoft to invoke multiple method parallel.
This method take Action which you can pass using the Lambda expression like following
System.Threading.Tasks.Parallel.Invoke(
                () => PrintStudentdetails(),
                () => PrintEmployeeDetails()
                );
 
Now run your application and you will see that its calling the class 2 time to avoid this situation LOCK keyword is the best way to controller from calling a class multiple time
So for change the Singleton class like following
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
   
      // Sealed ensures to restricted in the derived class
    
    public sealed class Singleton
    {
        private static int counter = 0;
        private static object obj = new object();

        /*
         * Private property initilized with null
         * ensures that only one instance of the object is created
         * based on the null condition
         */
        private static Singleton instance = null;

        /*
         * public property is used to return only one instance of the class
         * leveraging on the private property
         */
        public static Singleton GetInstance
        {
            get
            {
                if (instance == null)
                {
                    lock (obj)
                    {
                        if (instance == null)
                            instance = new Singleton();
                    }
                }
                return instance;
            }
        }
        /*
         * Private constructor ensures that object is not
         * instantiated other than with in the class itself
         */
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}



Now run your application you will see that this issue is resolved.

How to implement a Thread Safe singleton class : Locks are the best way to control thread race condition and they help us to overcome the present situation. Please refer to the Singleton.cs code for lock checks and double check locking.

For more details on double check locking please refer to the below article
https://en.wikipedia.org/wiki/Double-checked_locking 

Non-Lazy or Eager Loading : Eager loading is nothing but to initialize the required object before it’s being accessed.  Which means, we instantiate the object and keep it ready and use it when we need it. This type of initialization is used in lower memory footprints. Also, in eager loading, the common language runtime takes care of the variable initialization and its thread safety. Hence, we don’t need to write any explicit coding for thread safety. 
Non-Lazy or Eager in our application
Write the following code in singleton class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
   
      // Sealed ensures to restricted in the derived class
    
    public sealed class Singleton
    {
        private static int counter = 0;
       

        /*
         * Private property initilized with null
         * ensures that only one instance of the object is created
         * based on the null condition
         */
        private static readonly Singleton instance = new Singleton();

        /*
         * public property is used to return only one instance of the class
         * leveraging on the private property
         */
        public static Singleton GetInstance
        {
            get
            {              
                return instance;
            }
        }
        /*
         * Private constructor ensures that object is not
         * instantiated other than with in the class itself
         */
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}


When you will run application you will see following output




Modify eager loading to Lazy initialization using Lazy keyword
Singleton with Lazy keyword (.NET 4.0) : Lazy keyword provides support for lazy initialization. In order to make a property as lazy, we need to pass the type of object to the lazy keyword which is being lazily initialized. 

By default, Lazy objects are thread-safe.  In multi-threaded scenarios, the first thread which tries to access the Value property of the lazy object will take care of thread safety when multiple threads are trying to access the Get Instance at the same time. 

Therefore, it does not matter which thread initializes the object or if there are any thread race conditions that are trying to access this property.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SingletonApplication
{
   
      // Sealed ensures to restricted in the derived class
    
    public sealed class Singleton
    {
        private static int counter = 0;     
       
        private static readonly Lazy<Singleton> instance =
              new Lazy<Singleton>(() => new Singleton());

        public static Singleton GetInstance
        {
            get
            {
                return instance.Value;
            }
        }
      
        private Singleton()
        {
            counter++;
            Console.WriteLine("Counter Value " + counter.ToString());
        }
        /*
         * Public method which can be invoked through the singleton instance
         */
        public void PrintDetails(string message)
        {
            Console.WriteLine(message);
        }
    }
}




Difference between Lazy Loading and Non-lazy or Eagar Loading
Lazy Loading
1.   Improve the performance
2.   Avoid the unnecessary load till the point object is accessed
3.   Reduces the memory footprint on the start-up.
4.   Faster application load.
Non-Lazy loading
1.   Pre-Instantiation of the object
2.   Commonly used in lower memory footprints
When we should Lazy initialization
Now assume a situation that we need to assign some static property in the singleton class and those property need to be retrieve from the database ,in those situation we use last initialization as we do not need to retrieve these values till the singleton object is initialize .
Differences between Singleton and static classes

1.           Static is a keyword and Singleton is a design pattern
2.           Static classes can contain only static members
3.           Singleton is an object creational pattern with one instance of the class
4.           Singleton can implement interfaces, inherit from other classes and it aligns with   the OOPS concepts
5.           Singleton object can be passed as a reference
6.           Singleton supports object disposal
7.           Singleton object is stored on heap
8.           Singleton objects can be cloned