Singleton Design Pattern in C#

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 9

Singleton Design Pattern in C#

In this article, We will discuss :


What is Singleton design pattern ?
How to implement Singleton design pattern in C# ?
Effects of multithreading on singleton pattern
Implementing Double checked locking for singleton
Early instantiation of singleton
Fully Lazy instantiation of singleton
Implementing Singleton using Generics
Lazy<T> instantiation of singleton
Ways of breaking singleton
Uses of Singleton pattern
Singleton as Anti-pattern
Difference between static class and SIngleton Pattern
Summary

Singleton Design Pattern:

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

Standard Singleton implementation


To ensure the class has only one instance, we mark the constructor as private. So, we can
only instantiate this class from within the class.
We create a static variable that will hold the instance of the class.
Then, we create a static method that provides the instance of the singleton class. This
method checks if an instance of the singleton class is available. It creates an instance, if its
not available; Otherwise, it returns the available instance.

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3

public class Singleton {


private static Singleton instance;
private Singleton() {}
public static Singleton GetInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}

Issues with the standard implementation


The standard singleton implementation code works fine in Single threaded environment.
But in multithreaded environment, the GetInstance() code breaks :

1 public static Singleton GetInstance(){


2 if(instance == null){
3 instance = new Singleton();
4 }
5 return instance;
6 }

If two threads enter the if condition at the same time, then two instances of Singleton will be
created.

Handling Multithreading issue with standard singleton


implementation
We can synchronize the method. So that only one thread can access it at a time.In the
below implementation, the thread locks out the shared object, and then checks whether or
not the instance has been created before creating the instance.

1 public sealed class Singleton


2
{
3
private static Singleton instance = null;
4
private static readonly object Instancelock = new object();
5
6
private Singleton() {}
7
8
public static Singleton GetInstance
9
{
1
get
0
{
1
lock (Instancelock)
1
{
1
if (instance == null)
2
{
1
instance = new Singleton();
3
}

1
4
1
5
1
6
1
7
1
8
1
}
9
2
0
2
1
2
2

return instance;
}
}
}

This solves the multithreading issue. But it is slow since only one thread can access
GetInstance() method at a time.
We can use following approaches for this :

1 : Double checked locking


In this approach, we first check if the instance is created. If not, we synchronize.

1 public sealed class Singleton


2
{
3
private static Singleton instance = null;
4
private static readonly object Instancelock = new object();
5
6
private Singleton() {}
7
8
public static Singleton GetInstance
9
{
1
get
0
{
1
if (instance == null)
1
{
1
lock (Instancelock)
2
{
1
if (instance == null)
3
{
1
instance = new Singleton();
4
}
1
5
}
1
}
6
return instance;

1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5

}
}

2 : Early instance creation


We can choose to create the instance of Singleton class when the class is loaded.This is
thread-safe without using locking.

1
2
3
4
5
6
7
8
9
1
0

public class EarlySingleton {


//create instance eagerly
private static EarlySingleton instance = new EarlySingleton();
private EarlySingleton() {}
public static EarlySingleton GetInstance(){
return instance;//just return the instance
}
}

3 : Fully Lazy Instantiation


Here, instantiation is triggered by the first reference to the static member of the GetInstance
class, which only occurs in Instance.

1
2
3
4
5
public sealed class Singleton
6
{
7
private Singleton()
8
{
9
}
1
0
public static Singleton GetInstance { get { return GetInstance.instance; } }
1
1
private class GetInstance
1
{
2
// Explicit static constructor to tellcompiler
1
// not to mark type as beforefieldinit
3
static GetInstance()
1
{
4
}
1
5
internal static readonly Singleton instance = new Singleton();
1
}
6
1
7
1
8

4 : Singleton Implementation using Generics


This will give you a single instance and will effectively be lazy, because the static
constructor doesnt get called until Build() is called.

1
2
3 public class GenericSingleton<T> where T : new()
4
{
5
private static T ms_StaticInstance = new T();
6
7
public T GetInstance()
8
{
9
return ms_StaticInstance;
1
}
0
}
1
1 ...
1
GenericSingleton<SimpleType> instance = new GenericSingleton<SimpleType>();
2
SimpleType simple = instance.GetInstance();
1
3

5 : using Lazy<T> type


You need to pass a delegate to the constructor which calls the Singleton constructor
which is done most easily with a lambda expression.

1
2 public sealed class Singleton
3 {
4
private static readonly Lazy<Singleton> lazy =
5
new Lazy<Singleton>(() => new Singleton());
6
7
public static Singleton GetInstance { get { return lazy.Value; } }
8
9
private Singleton()
1
{
0
}
1 }
1

Breaking Singleton questions you may get in interviews :


Even though we avoided multiple instance creation of singleton class by using Double
checked locking or Eager instance creation, instances can still be created by :
cloning
reflection
Sub-classing singleton class

How to avoid Singleton instance creation by cloning ?


We can create a copy of an object using clone() method.
To avoid creating a clone of our singleton class, we can do the following :
Implement MethodwiseClone()
Override the clone() method and throw CloneNotSupportedException from it.

1 protected object MemberwiseClone()


2 {
3
throw new Exception("Cloning a singleton object is not allowed");
4 }

How to avoid Singleton class instance creation through


Reflection ?
To avoid instance creation through reflection, throw an exception from constructor if it
already has an instance.

1 private Singleton()
2 {
3
if (instance != null)
4
{
5
throw new Exception("Cannot create singleton instance through reflection");
6
}
7 }

How to avoid a subclass creating singleton instance ?


If you just provide a private constructor, a subclass cannot instantiate it to create another
instance.

Uses of Singleton Design Pattern :


Logger :
Singleton pattern is a good option for the Logger class when we want to create one log file
with the logged messages. If we have more than one instances of Logger in the application,
a new log will be created with every instance.

Cache :
We can use Singleton pattern to implement caches as that provides a single global access
to it.

Why singleton pattern is considered an Anti-pattern ?


Singletons arent easy to handle with unit tests. You cant control their instantiation and
they may retain state across invocations.

Memory allocated to an Singleton cant be freed.


In multithreaded environment, access to the singleton object may have to be guarded
(e.g. via synchronization).
Singletons promote tight coupling between classes, so it is hard to test

Difference between Static class and Singleton Pattern:


In c# a static class cannot implement an interface. When a single instance class needs to
implement an interface for some business reason or IoC purposes, you can use the
Singleton pattern without a static class.
You can clone the object of Singleton but, you can not clone the static class object
Singleton object stores in Heap but, static object stores in stack
A singleton can be initialized lazily or asynchronously while a static class is generally
initialized when it is first loaded

Summary:
In this article, we have discussed:

Different ways for Singleton Implementation in C#

Uses of Singleton Pattern

Why SIngleton Pattern is considered as Anti Pattern?

Difference between Static class and SIngleton Pattern

2016, admin. All rights reserved.

You might also like