Singleton Design Pattern C# Example
--
The Singleton design pattern is a creational design pattern that restricts the instantiation of a class to ensure that there is only one instance of that class created in the entire application. It provides a global point of access to that instance. This pattern is particularly useful when exactly one object is needed to coordinate actions across the system, such as a configuration manager, thread pool, database connection pool, or logging service.
Ensure a class has only one instance and provide a global point of access to it.
Here’s an example of implementing the Singleton design pattern in C#:
💻 Singleton Class
public class Singleton
{
private static Singleton instance;
private static readonly object lockObject = new();
public static Singleton GetInstance()
{
if (instance == null)
{
lock (lockObject)
{
if (instance == null)
{
instance = new Singleton();
}
}
}
return instance;
}
public void SomeMethod()
{
Console.WriteLine("Singleton method called.");
}
}
💻Program.cs Class: Main Class
using SingletonEXP;
Singleton _SingletonIns01 = Singleton.GetInstance();
_SingletonIns01.SomeMethod();
Singleton _SingletonIns02 = Singleton.GetInstance();
if (_SingletonIns01 == _SingletonIns02)
{
Console.WriteLine("Both instances are the same. Singleton pattern is working.");
}
else
{
Console.WriteLine("Singleton pattern failed.");
}
Output
In this example:
- The
Singleton
class has a private static instance and a private constructor. - The
GetInstance
method provides access to the Singleton instance. It uses double-check locking to ensure thread safety when creating the instance. - In the
Main
method, we demonstrate how to obtain the Singleton instance and verify that it is indeed a single instance.
When you run this program, you’ll see that both _SingletonIns01
and _SingletonIns02
are the same instance, confirming that the Singleton pattern ensures there is only one instance of the class throughout the application's lifetime.
Key Benefits of the Singleton Design Pattern
- Global Point of Access: It provides a single point of access to the instance, making it easy to manage and control access to shared resources or services.
- Lazy Loading: The instance is created only when needed, which can improve performance and resource utilization, especially in scenarios where the Singleton is resource-intensive.
- Thread Safety: When implemented correctly, the Singleton pattern can ensure thread safety, preventing multiple threads from creating multiple instances.
However, it’s important to note that Singleton can also introduce a global state, which can make code harder to test and reason about. Therefore, it should be used judiciously and only when there is a genuine need for a single, shared instance.
Modern programming languages and frameworks often provide tools and techniques for handling dependencies and singletons more effectively, such as using dependency injection containers or relying on built-in mechanisms for managing shared resources.