30
MarSingleton Design Pattern
⭐ .NET Design Patterns Course: Design Patterns in C# Online Training
Singleton Design Pattern - C#: An Overview
Singleton pattern falls under the Creational Pattern of Gang of Four (GOF) Design Patterns in .Net. It is a pattern that is one of the simplest design patterns. This pattern ensures that a class has only one instance. In this Design Pattern Tutorial, I would like to share what is Singleton pattern and how is it works.
What is the Singleton Design Pattern?
The singleton design pattern in C# is one of the most popular. In this pattern, a class has only one instance in the program, which serves as its global point of access. In other terms, a singleton is a class that only enables one instance of itself to be generated and typically provides easy access to that instance.
There are several approaches to implementing the singleton pattern in C#. The following are some common characteristics of a singleton pattern.
- A single constructor that is private and has no parameters
- The class has been sealed
- A static variable that holds a reference to the single produced instance
- A public and static method of obtaining the reference to the produced instance
Advantages of Singleton Design Pattern
- The singleton pattern can be used to implement interfaces.
- Can be lazy-loaded and has static initialization.
- It helps to conceal dependence.
- It gives a single point of access to a specific instance, making it simple to manage.
Disadvantages of Singleton Design Pattern
- Unit testing is rather tough because it brings a global state into an application.
- Locking reduces the opportunity for parallelism within a program.
Singleton class vs. Static methods
- A static class cannot be extended, although a singleton class can.
- A static class cannot be initialized, whereas a singleton class may.
- When a program that has a static class is loaded, the CLR automatically loads it.
How to Implement Singleton Pattern in C# code
There are various approaches to implementing the Singleton Pattern in C#.
- No thread-safe singleton.
- Thread-Safety Singleton.
- Thread-Safety Singleton with Double-Check Locking.
- Thread-safe without a lock.
- Using.NET 4's Lazy<T> type.
Singleton Pattern - UML Diagram & Implementation
The UML class diagram for the implementation of the Singleton design pattern is given below:
The classes and objects in the above UML class diagram are as follows:
Singleton
This is a class that is responsible for creating and maintaining its unique instance.
C# - Implementation Code
//eager initialization of singleton
public class Singleton
{
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton GetInstance
{
get
{
return instance;
}
}
}
////lazy initialization of singleton
public class Singleton
{
private static Singleton instance = null;
private Singleton() { }
public static Singleton GetInstance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
////Thread-safe (Double-checked Locking) initialization of singleton
public class Singleton
{
private static Singleton instance = null;
private Singleton() { }
private static object lockThis = new object();
public static Singleton GetInstance
{
get
{
lock (lockThis)
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
}
}
Eager initialization instantiates the singleton instance upon class loading, ensuring its availability but potentially wasting resources even when unneeded. Lazy initialization delays instance creation until the first request, conserving resources but perhaps causing a little delay upon first access. Thread-safe initialization (double-checked locking) ensures secure access in multithreaded contexts by synchronizing instance creation, preventing multiple instances, and reducing performance overhead.
Singleton Pattern - Example
C# - Sample Code
/// <summary>
/// The 'Singleton' class
/// </summary>
public class Singleton
{
// .NET guarantees thread safety for static initialization
private static Singleton instance = null;
private string Name{get;set;}
private string IP{get;set;}
private Singleton()
{
//To DO: Remove below line
Console.WriteLine("Singleton Intance");
Name = "Server1";
IP = "192.168.1.23";
}
// Lock synchronization object
private static object syncLock = new object();
public static Singleton Instance
{
get
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
lock (syncLock)
{
if (Singleton.instance == null)
Singleton.instance = new Singleton();
return Singleton.instance;
}
}
}
public void Show()
{
Console.WriteLine("Server Information is : Name={0} & IP={1}", IP, Name);
}
}
/// <summary>
/// Singleton Pattern Demo
/// </summary>
///
class Program
{
static void Main(string[] args)
{
Singleton.Instance.Show();
Singleton.Instance.Show();
Console.ReadKey();
}
}
The code uses a thread-safe singleton pattern for the class "Singleton," which ensures that only one instance exists and is shared throughout the program. It implements double-checked locking to reduce performance overhead while ensuring thread safety during instance formation. The singleton object stores server information (name and IP) and has a method for displaying it.
Output
When to use it?
Exactly one instance of a class is required.
Controlled access to a single object is necessary.
When we required no thread-safe singleton design pattern
Summary
The Singleton design pattern in C# assures that a class has only one instance across an application. It provides a single point of access, streamlines management, and includes features such as lazy loading and interface implementation. However, it can present issues like as unit testing difficulty and reduced parallelism. Use it when a single instance with controlled access is required, but be aware of the potential downsides.