Click here to Skip to main content
15,867,939 members
Articles / Programming Languages / C#
Article

Implementing the Singleton Pattern in C#

Rate me:
Please Sign up or sign in to vote.
2.46/5 (42 votes)
10 Mar 2008CPOL5 min read 59.6K   23   13
This article describes about design pattern namely Singleton Pattern.

Introduction

This article describes about design pattern namely Singleton Pattern.

<adlinks>

Often when developing large application we come across situation when the instance of the class has to be instantiated only once with global point of access to instance. In this scenario we can use one of the singleton pattern that are commonly available. Implementing singleton pattern ensures that a class will have only one instance created and also provides a global point of access to class instance.

Let us see some of the implementation :

Ist way of implementing Singleton Pattern in C#:

Look into the following code and then we can run through it,

using System;

public class SingletonExample
{

private static SingletonExample instance;

private SingletonExample () {}
public static SingletonExample Instance
{

get
{

if (instance == null)
{

instance = new SingletonExample ();

}

return instance;

}
}
}

The instance is created inside the Instance property method, this class can also be instantiated any subclass and other functionalities, though it may introduce unnecessary dependencies. You can notice here that instantiation is not performed until an object asks for an instance. This implementation is not a thread safe for multithreaded environments.. There can be two different threads that are evaluated for the check if (instance==null) and found it to be true, then both will create instances, this violates the singleton pattern. Also there might be a case when 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 checks have been passed.
This approach is called as lazy instantiation. This approach avoids instantiating unnecessary singletons classes when the application starts.

IInd way of implementing Singleton Pattern in C#: Static Initialization Pattern

In the previous example there were some short comes due to which it is not a thread safe implementation. The problem was the instancing of the objects. In this implementation we will see how to over come this problem.

public sealed class SingletonExample
{
private static readonly SingletonExample instance = new SingletonExample ();

private SingletonExample (){}

public static SingletonExample Instance
{
get
{
return instance;
}
}
}

As you can see above, the instance is created first time when any member of the class is referenced. The common language runtime takes care of the variable initialization. The class is declared as sealed to prevent any addition of instances. Also, the variable is marked readonly, so that it can be assigned only during the static initialization or in a class constructor.

This implementation relies on the CLR to initialize the variables. It resolves the two problem namely global access and control over the way class is instantiated. The public static property provides a global access point to the instance. Also, as the constructor is private, the Singleton class cannot be instantiated outside of the class itself. Thus there is the restriction on only one instance that can exist in the system. Here as the Singleton instance is referenced by a private static member variable, therefore the instantiation of the class is not created until the class is first referenced invoking Instance property. You can see that this is slightly differed form of lazy instantiation property

The drawback of this approach is the way instantiation is controlled, This is because the fact.NET Framework performs the initialization. As use of a nondefault constructor or perform any other tasks before the instantiation is no more available. Generally, static initialization is mostly preferred choice for implementing a Singleton in .NET.

IIIrd way of implementing Singleton Pattern in C#: Simple Multithreaded Singleton Pattern

There is another way of implementing a simple multithreaded singleton patter as shown below:

public sealed class SingletonExample
{
private static SingletonExample instance=null;
private static readonly object objectlockCheck = new object();

private SingletonExample ()
{
}

public static SingletonExample Instance()
{
lock (objectlockCheck)
{
if (instance==null)
instance = new SingletonExample ();
}
return instance;
}
}

This is simple thread-safe implementation. Here the thread obtains a lock on the shared object and then checks of the existence of instance before creating the new instance. This is most apt implementation as it resolves all the memories check issues like read occurs only after the lock is obtained and any write is done when the lock is released. Also this ensures the single thread creation. Still with this implementation there is the problem of performance that lock is acquired each time the instance is request for creation.

IVth way of implementing Singleton Pattern in C#: Multithreaded Singleton Pattern

When there is need for multithreaded environment or the ability to use a non default constructor or ability to perform some tasks before the instantiation is done the earlier approach will fail and we need to go for different approach.

<adlinks>

There might be situation when we cannot rely relying on the CLR to take care of thread safety. In such a situation the language advantage can be taken to ensure single instance of object is created among many threads. The solution for this is to use the Double-Check Locking to keep separate threads from creating new instances of the singleton class at the same time.
The following implementation allows only a single thread to lock as against the above mentioned flaw, when no instance of Singleton has yet been created:

using System;
public sealed class SingletonExample
{
private static volatile SingletonExample instance;
private static object objectlockCheck = new Object();
private SingletonExample () {}

public static SingletonExample Instance
{
get
{
if (instance == null)
{
lock (objectlockCheck)
{
if (instance == null)
instance = new SingletonExample ();
}
}

return instance;
}
}
}

In this way only one instance can is created and that to when there is a need for class instance. Also, the variable is declared as volatile which ensures that assignment to the instance variable is completed before the instance variable can be accessed. Finally, this approach uses an object of type objectlockCheck instance to lock on, rather than locking on itself, to avoid deadlocks. This double-check locking approach solves the thread concurrency problems this also avoids an exclusive locking with every call to the Instance property method.

Conclusion

You can see that the last implementation provides best performance, thread safety, and robustness, however there is complicated code involved with it. Similarly there can be tradeoffs between various important aspects before choosing a pattern.

Credits

Much of this is based on the MSDN article here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Professionally I am a Software Engineer. Have over 6 years of experience and specialize in Microsoft Tech. I have done most of my project in VB, ASP, ASP.NET (1.1 and 2.0), C# (1.1 and 2.0) with back end support of MS-Access, Oracle, MS - SQL server etc. Also worked as the DBA for MS SQL Server (2000, 2005 and 2008).

I have stamp of Brain Bench and Microsoft certified professional to enhance my skill set.

For any query, reach me at jaiprakash.bankoll@gmail.com. Will be very happy to respond back.

I am a brain bench certified professional view my brainbench transcript click here

PS: Am also know with the nick name of OracleQuest

Please write your comments or suggestion in my blog

Comments and Discussions

 
Generalgood article Pin
Donsw15-Feb-09 14:30
Donsw15-Feb-09 14:30 
GeneralMy vote of 1 Pin
Selvin4-Jan-09 22:45
Selvin4-Jan-09 22:45 
GeneralRe: My vote of 1 Pin
Jaiprakash M Bankolli25-Oct-09 23:28
Jaiprakash M Bankolli25-Oct-09 23:28 
GeneralRe: My vote of 1 Pin
SecureQuest31-Oct-09 6:38
SecureQuest31-Oct-09 6:38 
Generalc'mon.. if people continue to write "articles" about stuff that's been... Pin
Seishin#8-Mar-08 9:46
Seishin#8-Mar-08 9:46 
GeneralRe: c'mon.. if people continue to write "articles" about stuff that's been... Pin
Kel_8-Mar-08 12:38
Kel_8-Mar-08 12:38 
GeneralSerialization and singletons Pin
orenmh8-Mar-08 7:26
orenmh8-Mar-08 7:26 
GeneralRe: Serialization and singletons Pin
SecureQuest31-Oct-09 6:41
SecureQuest31-Oct-09 6:41 
Generalrecycled article, worn out subject Pin
Rob Graham8-Mar-08 4:04
Rob Graham8-Mar-08 4:04 
GeneralRe: recycled article, worn out subject Pin
leppie8-Mar-08 4:47
leppie8-Mar-08 4:47 
GeneralRe: recycled article, worn out subject Pin
SecureQuest8-Mar-08 6:35
SecureQuest8-Mar-08 6:35 
GeneralRe: recycled article, worn out subject Pin
Bert delaVega8-Mar-08 12:03
Bert delaVega8-Mar-08 12:03 
GeneralRe: recycled article, worn out subject Pin
Jaiprakash M Bankolli9-Mar-08 2:59
Jaiprakash M Bankolli9-Mar-08 2:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.