Singleton Pattern

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;
...

Print | posted on Thursday, October 06, 2005 3:46 PM

Comments on this post

# re: Singleton Pattern

Requesting Gravatar...
Yes, the singleton pattern can be very useful. I have found that I prefer to use a property rather than a function called GetInstance. This makes it intuitive to condense situations like the following down to just one line:

SingletonConnection singleConnection = SingletonConnection.GetInstance();
SqlConnection sqlConn = singleConnection.SqlConnection;

So, if you use a Property instead of GetInstance, you can end up with something like this:

SqlConnection sqlConn = SingletonConnection.Instance.SqlConnection;

Of course, you could just as easily say this:

SqlConnection sqlConn = singleConnection.GetInstance().SqlConnection;

Here's an example of what I'm talking about:

#region Singleton
private static ConnectionManager instance = null;
public static ConnectionManager Instance
{
get
{
if(instance == null)
instance = new ConnectionManager();

return instance;
}
}

private ConnectionManager()
{
this.InitilizeSingleton();
}
#endregion
Left by Dan Koster on Oct 06, 2005 7:38 PM

# re: Singleton Pattern

Requesting Gravatar...
Ive also been pointed towards an interesting blog entry by Brad Abrams about the double check locking pattern. "there is a better way to do volatile, and that is with an explicitly memory barrier before accessing the data member". It invloves the following modification to the code above:
...
lock (syncRoot)
{
if(uniqueInstance == null)
{
SingletonConnection newVal = new SingletonConnection();
System.Threading.Thread.MemoryBarrier();
SingletonConnection.uniqueInstance = newVal;
}
...

Left by Vivek Ayer on Oct 09, 2005 4:45 PM

# re: Singleton Pattern

Requesting Gravatar...
Thanks a lot!
Left by Jérôme De Cuyper on Nov 11, 2009 5:10 AM

Your comment:

 (will show your gravatar)