Thursday, 30 November 2017

singleton design pattern in depth using C-Sharp(C#)


         "Ensure a class only has one instance and provide a global access to it."


       The basic implementation of singleton in C# is very simple:
  1. Make the constructor private, so there is no way to instantiate the class from the outside.
  2. Store the instance in a private static field.
  3. Provide accessor method to the instance field.

I am taking a real-time example to understand the concept of singleton design pattern. Suppose your grandfather asks you to write a letter for him. The first thing you will do is buy a pen and a paper, you will write it and show it to your grandfather. If he wants some changes then what will you do? Will you rush to the market again and buy a new pen to implement the changes or you will use the same pen? so the best choice is that you will use the same old pen.

Now let's get a little technical, if you have created an object of a class once in your application then why not use the same object for that class everywhere, rather than flooding memory with unnecessary objects and this is what we call a Singleton Design Pattern, in other words, a single object of each class.

Now the question is, how to do it. Time to code.


public class Singleton
{   
 public void Check(string s)
    {
        Console.WriteLine(s);
    }
}


I have declared a simple class here having one method Check. If we want to call the Check method from other classes then we can do that by creating the object of the singleton class using the "new" operator, right? I will implement logic that will prevent instantiation of the class using the "new" operator, if we do not do this then developers will continue to create the objects. Confused? Don't create the object we used a private constructor like this:
public class Singleton
{
    private Singleton()
    {

    }
    public void Check(string s)
    {
        Console.WriteLine(s);
    }
}

Try to make the object of the class now using the "new" operator; it will throw a compile-time error. Until now our first objective has been completed. Let's move to the next step. We have prevented our class from being instantiated with the "new" operator. It is, therefore, our responsibility to provide some other way for the developer to create its object and access its method. To do that I will declare a method GetObject() that will create the object and return it to the calling function and in this method, I will check if an object of the class already exists; if it does then it will return the old object rather than creating a new one.
public class Singleton
{
    protected static Singleton _obj;
    private Singleton()
    {

    }
    public static Singleton GetObject()
    {
        if (_obj == null)
        {
            _obj = new Singleton();

        }
        return _obj;
    }
    public void Check(string s)
    {
        Console.WriteLine(s);
    }
}


You can see I have declared a static instance of the class _obj and in the GetObject() method I am checking if the instance is null; if it is then it will create a new instance and return it otherwise it will return the previously created object
.

Use it in your main function like this:
class Program
{
    static void Main(string[] args)
    {
        Singleton SingletonObject = Singleton.GetObject();
        SingletonObject.Check("Hello World");
        Console.ReadLine();
    }
}

Complete Code



using System;using System.Collections.Generic;using System.Linq;using System.Text;
namespace ConsoleApplication4
{
    class Program 

   {
        static void Main(string[] args)
        {
            Singleton SingletonObject = Singleton.GetObject();
            SingletonObject.Check("Hello World");
            Console.ReadLine();
        }
    }

    public class Singleton 

   {
        protected static Singleton _obj;
        private Singleton()
        {
 
        }
        public static Singleton GetObject()
        {
            if (_obj == null)
            {
                _obj = new Singleton();
            }
            return _obj;
        }
        public void Print(string s)
        {
            Console.WriteLine(s);
        }
    }
}


private static object syncRoot = new Object();

Article Extensions  

  •     
    The above Singleton is easy to understand the concepts but it is not Thread safe.

    /* Single with Thread Safe */


    Complete Code

    using System;using System.Collections.Generic;using System.Linq;using System.Text;
    namespace ConsoleApplication4
    {
        class Program    {
            static void Main(string[] args)
            {
                Singleton SingletonObject = Singleton.GetObject();
                SingletonObject.Check("Hello World");
                Console.ReadLine();
            }
        }

        public class Singleton 

       {
           protected static Singleton _obj;
          private static object syncRoot = new Object();
            private Singleton()
            {
     
            }
            public static Singleton GetObject()
            {
        if (_obj == null) 
             {
          lock (syncRoot) 
          {
                if (_obj == null)
                {
                    _obj = new Singleton();
                }
               }
           }
                return _obj;
            }
            public void Print(string s)
            {
                Console.WriteLine(s);
            }
        }
    }






1 comment: