Singleton Design Pattern ensures that a class has exactly one copy and provide a global access point to it
Real-life example:
- Logger
- One instance is preferred to avoid unintended consequences.
The class must be responsible for ensuring only one instance of itself exists.
public class Logger
{
private static Logger? _instance;
/// <summary>
/// Instance
/// </summary>
public static Logger Instance
{
get
{
if (_instance == null) //This is not thread safe.
{
_instance = new Logger();
}
return _instance;
}
}
protected Logger()
{
}
/// <summary>
/// Singleton Operation
/// </summary>
/// <param name="message"></param>
public void Log(string message)
{
Console.WriteLine(message);
}
}
Above code is not thread safe. If the instance is created by another thread, it will create another instance.
To resolve thread safe issue, Lazy<T> can be used as below.
public class LazyLogger
{
//Lazy<T>
private static readonly Lazy<LazyLogger> LazyLoggerInstance =
new Lazy<LazyLogger>(() => new LazyLogger());
/// <summary>
/// Instance
/// </summary>
public static LazyLogger Instance => LazyLoggerInstance.Value;
protected LazyLogger()
{
}
/// <summary>
/// Singleton Operation
/// </summary>
/// <param name="message"></param>
public void Log(string message)
{
Console.WriteLine(message);
}
}
When to Use Singleton Pattern
More real world example
Outcome of Singleton Pattern