Back to: Design Patterns in C# With Real-Time Examples
Singleton Design Pattern in C# with an Example
In this article, I will discuss the Singleton Design Pattern in C# with Examples. Please read our previous article discussing Shallow Copy and Deep Copy in C# with Examples. The Singleton Design Pattern in C# falls under the Creational Pattern Category. It belongs to the creational pattern category, dealing with object creation and manipulation. As part of this article, we will discuss the following pointers.
- What is Singleton Design Pattern?
- What are the Advantages of using the Singleton Design Pattern?
- Implementation Guidelines of Singleton Pattern in C#.
- Example of the Singleton Pattern using C#.
- Some Real-time scenarios where you can use the Singleton Design Pattern.
- What are the Disadvantages of using the Singleton Design Pattern in C#?
What is Singleton Pattern in C#?
The Singleton pattern is a design pattern that restricts the instantiation of a class to one object and provides a way to access its object. This is useful when exactly one object is needed to coordinate actions across the system. That means we need to use the Singleton Design Pattern in C# to ensure that only one instance of a particular class will be created and provide simple global access to that instance for the entire application.
As you can see in the above diagram, different clients (Client A, Client B, and Client C) are trying to get the singleton instance. Once the client gets the singleton instance, they can invoke the methods (Method 1, Method 2, and Method n) using the same instance. If this is confusing, don’t worry; we will discuss it with practice.
Implementation Guidelines of Singleton Design Pattern in C#:
The following are the guidelines to implement the Singleton Design Pattern in C#.
- We need to declare a constructor that should be private and parameterless. This is required because it will restrict the class from being instantiated from outside the class. It only instantiates from within the class.
- The class should be declared sealed, ensuring it cannot be inherited. This is going to be useful when you are dealing with the nested class. We will discuss this scenario with an example in our next article.
- We must create a private static variable referencing the class’s singleton instance.
- We also need to create a public static property/method that will return the singleton instance of the class. This method or property first checks whether an instance of the singleton class is created. If the singleton instance is created, it returns that instance; otherwise, it will create an instance and then return it.
Example of Singleton Design Pattern using C#
Let us understand the Singleton Design pattern in C# with Examples. We can implement the Singleton Design Pattern in C# in many ways. They are as follows. We will discuss all the following methods to implement the Singleton Design Pattern in C#.
- No Thread-Safe Singleton Design Pattern in C#
- Thread-Safety Singleton Implementation using Lock.
- Implementing Thread-Safety Singleton Design Pattern using Double-Check Locking.
- Using Eager Loading to Implement Thread-Safety Singleton Design Pattern
- Using Lazy<T> Generic Class to Implement Lazy Loading in Singleton Design Pattern.
No Thread-Safe Singleton Design Pattern Implementation in C#
This article will discuss the No Thread-Safe Singleton Design Pattern implementation in C#. The rest of the implementations will be discussed individually in our upcoming articles. Let us understand how to implement the No Thread Safe Singleton Design Pattern in C# with an Example. First, create a class file, Singleton.cs, and then copy and paste the following code. The following code is self-explained, so please go through the comment lines for a better understanding.
using System; namespace SingletonDemo { public sealed class Singleton { //This variable value will be increment by 1 each time the object of the class is created private static int Counter = 0; //This variable is going to store the Singleton Instance private static Singleton Instance = null; //The following Static Method is going to return the Singleton Instance public static Singleton GetInstance() { //If the variable instance is null, then create the Singleton instance //else return the already created singleton instance //This version is not thread safe if (Instance == null) { Instance = new Singleton(); } //Return the Singleton Instance return Instance; } //Constructor is Private means, from outside the class we cannot create an instance of this class private Singleton() { //Each Time the Constructor called, increment the Counter value by 1 Counter++; Console.WriteLine("Counter Value " + Counter.ToString()); } //The following can be accesed from outside of the class by using the Singleton Instance public void PrintDetails(string message) { Console.WriteLine(message); } } }
Here, we created the Singleton class as sealed, which ensures that the class cannot be inherited from the derived classes. The class is created with a private parameterless constructor, ensuring that the class will not be instantiated from outside the class. But we can create instances within the same class. Again, we declared the instance variable private and initialized it with the null value, ensuring that only one class instance will be created based on the null condition. The public method, GetInstance, returns only one instance of the class by checking the value of the private variable instance. The public method PrintDetails can be invoked from outside the class through the singleton instance.
We are done with our first version of the singleton design pattern implementation, which is not thread-safe. Let us see how we can use the above Singleton class in our Main method of Program class. So, modify the Main method of the Program class as follows. As you can see in the code below, we are calling the GetInstance() static method of the Singleton class, which will return the Singleton instance, and then, using that Singleton instance, we are calling the PrintDetails. And we are doing this two times.
using System; namespace SingletonDemo { class Program { static void Main(string[] args) { //Call the GetInstance static method to get the Singleton Instance Singleton fromTeachaer = Singleton.GetInstance(); fromTeachaer.PrintDetails("From Teacher"); //Call the GetInstance static method to get the Singleton Instance Singleton fromStudent = Singleton.GetInstance(); fromStudent.PrintDetails("From Student"); Console.ReadLine(); } } }
Run the application, and it will give you the following output.
As you can see in the above output, it clearly shows that the private constructor is executed only once, even though we have called the GetInstance method twice and printed the counter value as 1. Hence, it proves that the singleton instance is created only once. The way we implement the singleton design pattern in the above example is not to be thread-safe. It means in a multithreaded environment, it can create multiple instances of the singleton class. We will discuss making the singleton class thread-safe in our Thread-Safe Singleton Design Pattern article.
What are the Advantages of using the Singleton Pattern in C#?
The Advantages of using the Singleton Design Pattern in C# are as follows.
- The first and most important advantage of using the singleton design pattern in C# is that it takes care of concurrent access to the shared resource. That means if we share a resource with multiple clients simultaneously, then concurrent access to that resource is well managed by the singleton design pattern.
- It can be lazy-loaded and also has Static Initialization.
- To share common data, i.e., master and configuration data, which is not frequently changed in an application. In that case, we need to cache the objects in memory.
- It is easy to maintain as it provides a single global access point to a particular instance.
- To reduce the overhead of instantiating a heavy object again and again.
What are the Disadvantages of using the Singleton Design Pattern in C#?
The disadvantages of using the Singleton Design Pattern in C# are as follows:
- Unit testing is very difficult because it introduces a global state into an application.
- It reduces the potential for parallelism within a program because to access the singleton instance in a multi-threaded environment, you need to serialize the object using locking.
In the next article, I will discuss Why we Need to use the Sealed Keyword in the Singleton Class, as we already have a private constructor. In this article, I explain the basic concepts of the Singleton Design Pattern in C# with Examples. I hope you understand why we need the Singleton Design Pattern in C# with Examples.
Very nice. Easy to understand.
Excellent , explanation is very good
Very good explanation..
Very easily to understand.Thanks a lot
nice
Using “Get” in property names is not a good idea (and doesn’t meet the .NET naming standards).
You basically end up with a method called get_GetInstance !
Just call it “Instance” (or “SingleInstance” if you prefer).
Alternatively, you could make it a method: public SingleInstance GetInstance() …
Well explained. Thanks.
I guess this is not thread safe.
Yes. This is not thread-safe. We are explaining the concept step by step. Please proceed with the next article.
https://dotnettutorials.net/lesson/thread-safe-singleton-design-pattern/
easy to understand .. well explained
thank you so much for this clean and very helpful explanation