What is the Singleton Pattern?
Wikipedia describes it as:
In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.
Sometimes this is because we need shared state across the application, or for efficiency reasons – maybe for I/O operations. There are heavy debates on when or if you should even try to do this, but there are definitely use cases. Be careful when you have data/properties that need to be shared across a system through single instantiation, it may be a code smell. If it is what you need, here are some implementation details.
The biggest problems you are going to run into while implementing this pattern is thread safety. Let’s look a very straightforward, basic implementation of the Singleton.
Reminder, Pluralsight has many courses on different design patterns in many different languages and implementations, and they have a FREE trial!
Start a 10-day free trial at Pluralsight
Examples are in C#.
public class Singleton {
private static Singleton instance;
private Singleton() {
// Things that must only happen once
}
public static Singleton Instance() {
if (instance == null)
{
instance = new Singleton()
}
return instance;
}
public void DoSomething() {
// Must be thread safe
}
}
We may run into threading issues where two threads try to access the constructor at the same time.
We could do some craziness like doing explicit thread locking and double checking.
public class Singleton {
private static Singleton instance;
private static readonly object mutex = new object();
private Singleton() {
// Things that must only happen once
}
public static Singleton Instance() {
if (instance == null) {
lock (mutex) {
if (instance == null)
{
instance = new Singleton()
}
}
}
return instance;
}
public void DoSomething() {
// Must be thread safe
}
}
Unless your class is very IO heavy or doing other heavy lifting, you probably won’t run into huge performance costs by thread locking, but it still isn’t very pretty, and can cause it’s own problems.
By understanding the mechanics of static classes and their static constructor, we can understand that .NET does a pretty good job of only letting one thread inside of a static constructor at a time, so an empty static constructor solves a lot of our problems and even forces a certain level of laziness in instantiation, but isn’t perfect.
static Singleton() {}
If being lazy is super important to you, you can go the extra mile and create an internal holder for your singleton.
public class Singleton {
private static class SingletonHolder {
internal static readonly Singleton instance = new Singleton();
// Empty static constructor forces laziness
static SingletonHolder() {}
}
private Singleton() { Console.WriteLine("Instantiate") }
public static Singleton Instance { get { return SingletonHolder.instance; } };
// Stateless method
public void SayHi() {
Console.WriteLine("Hello");
}
}
// Example usage
public void main() {
Singleton.SayHi();
Console.WriteLine("Before Usage");
Singleton s = Singleton.Instance;
/*
Output:
Hello
Before Usage
Instantiate
*/
}
In this example, simple methods that don’t need access to the internal state that you are trying to share across the application, don’t even need an instance of the class to execute and will not instantiate the class until you actually ask for the instance.
In .NET4 and later, you can use built-in language features to get real lazy implementation.
public class Singleton {
private static readonly Lazy lazyInstance =
new Lazy(() => new Singleton(), isThreadSafe: true)
private Singleton() {}
public static Singleton Instance { get { return instance.Value; } };
public void SayHi() {}
}