Working With Singleton Design Pattern In Real Time Projects

Singleton pattern is a most commonly used design pattern, which is frequently used in most of the projects. In this article, I will explain  what Singleton pattern is and how to work with Singleton pattern in projects.The main agenda of this article is-
  • Introduction about Singleton pattern.
  • Memory allocation by a class object.
  • Singleton pattern in details.
  • Singleton pattern example in console Application.
  • Lazy initialization.
  • Singleton in multi-threaded environment.
  • Creating a Logger in MVC to trace an error, using Singleton pattern.
Introduction

Singleton pattern is one of the most important design patterns in a programming language.This type of design pattern comes under creational pattern, as it provides one of the best ways to create an object.

This pattern ensures that a class has only one instance and provides a global point of access to it.

As per the definition of Wikipidia,

In software engineering, Singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful, when exactly one object is needed to coordinate the actions, across the system. The concept is sometimes generalized to the systems, which operates more efficiently when only one object exists or that restricts the instantiation to a certain number of objects. The term comes from the mathematical concept of a singleton.

Before discussing more about Singleton pattern, let me discuss what will happen when we create more then one object for a single Class.
 
What happen when  we create multiple object of a  Class?
 
A class is like a blueprint that specifies, what the type can do. An object is basically a block of memory, which has been allocated to the blueprint. A program may create many objects of the same class. Objects are also called the instances and are stored in Heap memory location. I will now explain what happens when we will create an object of the class.
  • When we create an object of a class a memory is allocated in the RAM (Random Access Memory).
  • RAM is volatile and the information stored will be lost when you close the program or on any Power loss.
  • RAM (Random Access Memory) is made up of cells. Each cell has its own unique address, where exactly the object will be stored.


If we create multiple objects of the same class, multiple memory will be allocated to the same object but with different cell addresses in RAM.

The figure, given below, will explain, how the memory is allocated to RAM while multiple instance is created, using new keyword.


  • Stack is used for static memory allocation and Heap for dynamic memory allocation. Both are stored in the computer's RAM .


    Thus, in this way, the memory is wasted, while we create a new instance of a class in every call. Thus, to prevent this thing, we can use this "singleton" pattern, which will restrict the user to create more than a single object. 

    A Singleton should be used when managing access to a resource, which is shared by the entire Application
    or we can say when we want to make a centralized global object. 
Description
 
 
In Singleton pattern only one object is created for the class and that object is shared across all the clients,this approach is used when we want to make something centralized. This approach is used in creating a logged file for the whole Application. This is because, whatever error is generated for all the clients, we need to track it from a single file. Thus, we need a singleton pattern here.
 
In this case, if we follow singlecall (one object for each UI) approach, there is a chance of removing the first user errors from the file, when the second user encounters some error, and here only the second user error will be logged in the logged file.

To implement Singleton pattern in our project, we have to follow three main steps, which are-
  • Declare a private constructor for the class for which you want to make Singleton.
  • Declare a static variable for that class.
  • Create a static method for that class and assign the object to the declared static variable.
Private Constructor
  1. A private constructor cannot be inherited. If you try to inherit a private constructor, it will give the error and one more important point about the private constructor is if you want to create an object of the class, it will give an error and hence does not allow  you to create an object.
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Threading.Tasks;  
    6.   
    7. namespace oops1  
    8. {  
    9.     public class Toyota  
    10.     {  
    11.          
    12.         private Toyota()  
    13.         {  
    14.   
    15.   
    16.         }  
    17.     }  
    18.     public class Mycar:Toyota  
    19.     {   
    20.         static void Main(string[] args)  
    21.         {  
    22.              
    23.             Console.ReadLine();  
    24.   
    25.   
    26.         }  
    27.     }  
    28.   
    29.   
    30. }  
    It will show the error message, given below-

     

  2. Now the question is, how will we consume the members of a class that has a private constructor. Thus, if we are taking a private constructor for a class, we have to declare all the members of the class as static.This is because the static member of a class can be called or consumed by only the class name.
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using System.Threading.Tasks;  
    6.   
    7. namespace oops1  
    8. {  
    9.     public class Toyota  
    10.     {  
    11.          
    12.          
    13.         private Toyota()  
    14.         {  
    15.   
    16.   
    17.         }  
    18.         public static string name;  
    19.         public static string getData()  
    20.         {  
    21.             return name;  
    22.         }  
    23.     }  
    24.     public class Mycar  
    25.     {   
    26.         static void Main(string[] args)  
    27.         {  
    28.             Toyota.name = "India";  
    29.            Console.WriteLine(Toyota.name);  
    30.              
    31.             Console.ReadLine();  
    32.   
    33.   
    34.         }  
    35.     }  
    36.   
    37.   
    38. }  
Thus, we have seen the importance of Private constructor. This private constructor plays an important role in singleton pattern in any language.
Now, we will see, how to implement Singleton pattern, using private constructor. I am doing one Console Application to make use of Singleton pattern, given below-
  1. public class Toyota  
  2.    {  
  3.        private Toyota()  
  4.        {  
  5.   
  6.        }  
  7.        public static Toyota obj;  
  8.        public static Toyota GetInstance()  
  9.        {  
  10.            if(obj==null)  
  11.            {  
  12.                obj = new Toyota();  
  13.   
  14.            }  
  15.            return obj;  
  16.   
  17.        }  
  18.        public string getDetails()  
  19.        {  
  20.            return "India";  
  21.        }  
  22.         
  23.        
  24.    
  25.    }  
Here, I have designed this class as singleton class. Here, I have taken one static variable and one static method as GetInstance. I am checking whether an object is null or not.When the Application starts for the first time, the value will be null and then it will contain some value until the end of the programme and would not execute the if condition and thus does not create the object.

Now, call from another class.

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. nam
    espace
     oops1  
  8. {  
  9.     public class Car  
  10.     {  
  11.   
  12.         static void Main(string[] args)  
  13.         {  
  14.             Toyota toy = Toyota.GetInstance();  
  15.            string x= toy.getDetails();  
  16.             Console.WriteLine(x);  
  17.             Console.ReadLine();  
  18.         }  
  19.     }  
  20. }  
The implementation here is straightforward. The constructor of Toyota is private. Thus, it is not possible to instantiate it from outside. The only way to get an instance is to call static GetInstance() method. GetInstance() first checks, whether an instance is already created or not. If not, then it creates an instance, refersit via private static member instance and then returns it. If already created, it returns the previously created instance. Thus, the first call GetInstance() instantiates a Toyota object only and any further call returns the same object. Also note, the object is not instantiated until GetInstance() is called, i.e. we only create, when actually required.
 
Now, I can create one more object like-
  1. static void Main(string[] args)  
  2.        {  
  3.            Toyota toy = Toyota.GetInstance();  
  4.            Toyota toy1 =Toyota.GetInstance();  
  5.            string x= toy.getDetails();  
  6.            Console.WriteLine(x);  
  7.            Console.ReadLine();  
  8.        }  
 In this case, even if we will try to create a new object, it will not execute the if condition and gives up the first object.



For another object, this obj!=null now and and it will not go to execute the condition.



This is how it fails to the condition and gives the first object reference.

 

In this way, we can implement Singleton pattern in our project. Now, the main concept is about handling multiple request in Singleton pattern.
 
Lazy initialization
 
To increase the performance of the Applications, one has to be very cautious, how and when objects are created and destroyed.

An early creation of an object is very dangerous, as it has a delayed clean-up. When an object is created before it is actually required, the object finds itself residing in a memory stack at much father location from the place it is referenced – hence requiring more POP and PUSH statements to retrieve its value each time it is referenced.

To optimize this, C# 4.0 introduced Lazy object loading. Lazy loading refers to the creating and initializing of the objects only, when it is required for the first time. This means, you can define the object, whenever you wish to, but it actually gets created only, when you access its method/property/function. This article talks about Lazy loading in C# 4.0.

As per Wiki,

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value or some other expensive process until the first time it is needed.
 
Singleton in multi-threaded environment

As we have seen before, the above is not thread-safe. Two different threads could both have evaluated the test if (obj==null) and found it to be true, and create both the instances, which violate the Singleton pattern. Note, in fact, the instance may already have been created before the expression is evaluated, but the memory model doesn't guarantee that the new value of instance will be seen by other threads unless suitable memory barriers have been passed.

Thus, I have written the following program for thread safe environments.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6.   
  7. namespace oops1  
  8. {  
  9.     public class Toyota  
  10.     {  
  11.         private Toyota()  
  12.         {  
  13.   
  14.         }  
  15.         public static Toyota obj;  
  16.         private static readonly object mylockobject = new object();  
  17.         public static Toyota GetInstance()  
  18.         {  
  19.             lock (mylockobject)  
  20.             {  
  21.                 if (obj == null)  
  22.                 {  
  23.                     obj = new Toyota();  
  24.   
  25.                 }  
  26.             }  
  27.             return obj;  
  28.   
  29.         }  
  30.         public string getDetails()  
  31.         {  
  32.             return "India";  
  33.         }  
  34.          
  35.         
  36.      
  37.     }  
  38.   
  39.   
  40. }  
Here, the output is produced, when we will call the method.
 

Real time implementation of Singleton Pattern in MVC project.

Here, I have created an MVC project, where I have used my Data Access Layer(connection.cs) as a Singleton class as follows-
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Data;  
  6. using System.Data.SqlClient;  
  7. using System.Configuration;   
  8.   
  9. namespace SingleTon  
  10. {  
  11.     public class Connection  
  12.     {  
  13.         SqlCommand cmd;  
  14.         DataSet ds;  
  15.         DataTable dt;  
  16.         SqlDataAdapter da;  
  17.         private static Connection obj = null;  
  18.         private static readonly object mylockobject = new object();  
  19.         public static  Connection getInstance()  
  20.         {  
  21.             lock(mylockobject)  
  22.             {  
  23.                 if (obj == null)  
  24.                 {  
  25.                     obj = new Connection();  
  26.                 }  
  27.   
  28.             }  
  29.              
  30.             return obj;  
  31.         }  
  32.   
  33.         private Connection()  
  34.         {  
  35.   
  36.         }  
  37.         public static SqlConnection connect()  
  38.         {  
  39.             string s = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;  
  40.                   
  41.   
  42.             SqlConnection con = new SqlConnection(s);  
  43.             if (con.State == ConnectionState.Closed)  
  44.             {  
  45.                 con.Open();  
  46.             }  
  47.             else  
  48.             {  
  49.                 con.Close();  
  50.             }  
  51.                 return con;  
  52.   
  53.         }  
  54.         public DataTable Selectall(string query)  
  55.         {  
  56.             da = new SqlDataAdapter(query, Connection.connect());  
  57.             dt = new DataTable();  
  58.             da.Fill(dt);  
  59.             return dt;  
  60.   
  61.   
  62.         }  
  63.         public bool DML(string query)  
  64.         {  
  65.             cmd = new SqlCommand(query, Connection.connect());  
  66.            int x= cmd.ExecuteNonQuery();  
  67.             if(x==1)  
  68.             {  
  69.                 return true;  
  70.   
  71.             }  
  72.             else  
  73.             {  
  74.                 return false;  
  75.   
  76.             }  
  77.             
  78.              
  79.   
  80.         }  
  81.   
  82.     }  
  83. }  
Here, my connection string is defined in web.config section.
  1. <connectionStrings>
    <add name="Connect" connectionString="Data Source=Debendra;Initial Catalog=Debendra;User ID=*****;Password=*****" />
    </connectionStrings>

Here, my controller class is given below-.

From the controller class, we call the connection class, where a private constructor is defined and only once object is created and that object is used, across the project.

Here, my model is defined-
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. namespace SingleTon.Models  
  7. {  
  8.     public class Employee  
  9.     {  
  10.         public string name { getset; }  
  11.         public int RollNo { getset; }  
  12.     }  
  13. }  
Here, my view is-
  1. @model SingleTon.Models.Employee  
  2.   
  3. @{  
  4.     ViewBag.Title = "SaveData";  
  5. }  
  6.   
  7. <h2>SaveData</h2>  
  8.   
  9.   
  10. @using (Html.BeginForm())   
  11. {  
  12.     @Html.AntiForgeryToken()  
  13.       
  14.     <div class="form-horizontal">  
  15.         <h4>Employee</h4>  
  16.         <hr />  
  17.         @Html.ValidationSummary(true""new { @class = "text-danger" })  
  18.         <div class="form-group">  
  19.             @Html.LabelFor(model => model.name, htmlAttributes: new { @class = "control-label col-md-2" })  
  20.             <div class="col-md-10">  
  21.                 @Html.EditorFor(model => model.name, new { htmlAttributes = new { @class = "form-control" } })  
  22.                 @Html.ValidationMessageFor(model => model.name, ""new { @class = "text-danger" })  
  23.             </div>  
  24.         </div>  
  25.   
  26.         <div class="form-group">  
  27.             @Html.LabelFor(model => model.RollNo, htmlAttributes: new { @class = "control-label col-md-2" })  
  28.             <div class="col-md-10">  
  29.                 @Html.EditorFor(model => model.RollNo, new { htmlAttributes = new { @class = "form-control" } })  
  30.                 @Html.ValidationMessageFor(model => model.RollNo, ""new { @class = "text-danger" })  
  31.             </div>  
  32.         </div>  
  33.   
  34.         <div class="form-group">  
  35.             <div class="col-md-offset-2 col-md-10">  
  36.                 <input type="submit" value="Create" class="btn btn-default" />  
  37.             </div>  
  38.         </div>  
  39.     </div>  
  40. }  
  41.   
  42. <div>  
  43.     @Html.ActionLink("Back to List""Index")  
  44. </div>  
  45.   
  46. @section Scripts {  
  47.     @Scripts.Render("~/bundles/jqueryval")  
  48. }  
Here, my controller Class is-
  1. public ActionResult SaveData()  
  2.       {  
  3.           return View();  
  4.   
  5.       }  
  6.       [HttpPost]  
  7.   
  8.       public ActionResult SaveData(employee emp)  
  9.       {  
  10.           try  
  11.           {  
  12.               bool res = false;  
  13.               Connection obj = Connection.getInstance();  
  14.   
  15.               res = obj.DML("insert into employee(Name,RollNo)values('" + emp.Name + "','" + emp.RollNo + "')");  
  16.               if (res == true)  
  17.               {  
  18.                   return Content("<script language='javascript' type='text/javascript'>alert('Save Successfully');</script>");  
  19.   
  20.               }  
  21.               else  
  22.               {  
  23.                   return Content("<script language='javascript' type='text/javascript'>alert('Data not saved please try again.');</script>");  
  24.   
  25.               }  
  26.   
  27.   
  28.           }  
  29.           catch (Exception ex)  
  30.           {  
  31.               Logger obj = Logger.getInstance();  
  32.               obj.logError(ex.Message, 1);  
  33.                
  34.           }  
  35.            
  36.           return View();  
  37.       }  
Here, in catch block, we have the code, given below-

 
 My singleton Logger class is given below, which is used to trace and write the error, found in the project-
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. namespace SingleTon  
  7. {  
  8.     public class Logger  
  9.     {  
  10.   
  11.         private static System.IO.StreamWriter _Output = null;  
  12.         private static Logger _Logger = null;  
  13.         private static Object _classLock = typeof(Logger);  
  14.         public static string _LogFile = @"C:\Users\Debendra\documents\visual studio 2015\Projects\SingleTon\SingleTon\LogDetails.log";  
  15.         public static int _LogLevel = 1;  
  16.   
  17.         private Logger()  
  18.         {  
  19.   
  20.         }  
  21.   
  22.         public static Logger getInstance()  
  23.         {  
  24.             //lock object to make it thread safe  
  25.             lock (_classLock)  
  26.             {  
  27.                 if (_Logger == null)  
  28.                 {  
  29.                     _Logger = new Logger();  
  30.   
  31.                 }  
  32.             }  
  33.             return _Logger;  
  34.         }  
  35.   
  36.         public  void logError(string s, int severity)  
  37.         {  
  38.             try  
  39.             {  
  40.                 if (severity <= _LogLevel)  
  41.                 {  
  42.                     if (_Output == null)  
  43.                     {  
  44.                         _Output = new System.IO.StreamWriter(_LogFile, true, System.Text.UnicodeEncoding.Default);  
  45.                     }  
  46.   
  47.                     _Output.WriteLine(System.DateTime.Now + " | " + severity + " | " + s, new object[0]);  
  48.   
  49.                     if (_Output != null)  
  50.                     {  
  51.                         _Output.Close();  
  52.                         _Output = null;  
  53.                     }  
  54.                 }  
  55.             }  
  56.             catch (Exception ex)  
  57.             {  
  58.                 Console.WriteLine(ex.Message, new object[0]);  
  59.             }  
  60.         }  
  61.   
  62.         public static void closeLog()  
  63.         {  
  64.             try  
  65.             {  
  66.                 if (_Output != null)  
  67.                 {  
  68.                     _Output.Close();  
  69.                     _Output = null;  
  70.                 }  
  71.             }  
  72.             catch (Exception ex)  
  73.             {  
  74.                 Console.WriteLine(ex.Message, new object[0]);  
  75.             }  
  76.         }  
  77.     }  
  78. }   
In this way, we can create a centralized logger file in Singleton pattern, which will update all the errors that occurred in the Application.Thus, we can check it in the single file without missing any error.

Now,
  • Right click on the Project
  • Add New Item and add a TextFile as follows-



  • Rename it as "LogDetails.log" and save the file. Put the file path in the log class, as shown above.

    Now, my view to enter the details of the user is given below-
    1. @model SingleTon.Models.Employee  
    2.   
    3. @{  
    4.     ViewBag.Title = "SaveData";  
    5. }  
    6.   
    7. <h2>SaveData</h2>  
    8.   
    9.   
    10. @using (Html.BeginForm())   
    11. {  
    12.     @Html.AntiForgeryToken()  
    13.       
    14.     <div class="form-horizontal">  
    15.         <h4>Employee</h4>  
    16.         <hr />  
    17.         @Html.ValidationSummary(true""new { @class = "text-danger" })  
    18.         <div class="form-group">  
    19.             @Html.LabelFor(model => model.name, htmlAttributes: new { @class = "control-label col-md-2" })  
    20.             <div class="col-md-10">  
    21.                 @Html.EditorFor(model => model.name, new { htmlAttributes = new { @class = "form-control" } })  
    22.                 
    23.             </div>  
    24.         </div>  
    25.   
    26.         <div class="form-group">  
    27.             @Html.LabelFor(model => model.RollNo, htmlAttributes: new { @class = "control-label col-md-2" })  
    28.             <div class="col-md-10">  
    29.                 @Html.EditorFor(model => model.RollNo, new { htmlAttributes = new { @class = "form-control" } })  
    30.                  
    31.             </div>  
    32.         </div>  
    33.   
    34.         <div class="form-group">  
    35.             <div class="col-md-offset-2 col-md-10">  
    36.                 <input type="submit" value="Create" class="btn btn-default" />  
    37.             </div>  
    38.         </div>  
    39.     </div>  
    40. }  
    41.   
    42. <div>  
    43.     @Html.ActionLink("Back to List""Index")  
    44. </div>  
    45.   
    46. @section Scripts {  
    47.     @Scripts.Render("~/bundles/jqueryval")  
    48. }  

    Thus, it will work fine for all the data, you want to insert.

    To raise an error, I will make some logic change as I will try to insert the name in RollNo column also. Thus the error will be captured and is shown as follows-



  • In this way, we can implement Singleton pattern in our project. Implementing any design pattern depends upon the condition. We can't implement the design pattern anywhere. Before implementing, we need to check the condition whether this pattern will be suitable for the condition or not. 
Hope, this article will make you understand the basic concept of Singleton pattern. If you find any problem in my code, please comment, so that I will also learn and improve my code.


Similar Articles