The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it. There are many objects we only need one of: thread pools, caches, objects that handle common settings, objects used for logging, objects that act as device drivers etc. In this case we take a class and let it manage a single instance of itself. We then prevent any other class from creating a new instance on its own and we provide a global access point to the instance.
Here is a simple example of the Single Pattern. A class that always provides a single connection to a database.
using System;
using System.Data.SqlClient;
namespace Vivek.Generic
{
public class SingletonConnection
{
#region -- private variables --
private volatile static SingletonConnection uniqueInstance;
private static object syncRoot = new Object();
private static string strConnectionString;
private SqlConnection sqlConnection;
#endregion
#region -- public properties --
public static string ConnectionString
{
get { return strConnectionString; }
set { strConnectionString = value; }
}
public SqlConnection SqlConnection
{
get { return sqlConnection; }
}
#endregion
#region -- private constructor --
private SingletonConnection()
{
sqlConnection = new SqlConnection(strConnectionString);
}
#endregion
#region -- Get Single Instance --
public static SingletonConnection GetInstance()
{
if(uniqueInstance == null)
{
lock (syncRoot)
{
if(uniqueInstance == null)
{
uniqueInstance = new SingletonConnection();
}
}
}
return uniqueInstance;
}
#endregion
}
}
Note:
To deal with multithreading we use the volatile and lock keywords.
The volatile modifier is used for a field that is accessed by multiple threads. Using the volatile modifier ensures that one thread retrieves the most up-to-date value written by another thread.
lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released.
And our class can be used like this...
...
SingletonConnection.ConnectionString = "Data Source=Vivek;Initial Catalog=Northwind;Integrated Security=SSPI;";
SingletonConnection singleConnection = SingletonConnection.GetInstance();
SqlConnection sqlConn = singleConnection.SqlConnection;
...