The Singleton Pattern
The Singleton pattern is useful when you want to ensure that only one instance of a class exists in your application. (For other design patterns, see Why Know Design Patterns?)
Definition
The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.1
Why use the Singleton pattern?
In some situations, you want to ensure that there’s only one instance of a class running. For example, if you have a class that manages databases connections / pools, having several instances of that class will cause all sorts of problems.
Implementation
The traditional way of implementing the Singleton pattern is with a bit of static / not-static trickery and a private constructor:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class Singleton
{
// this is a static property of the class itself (!)
static Singleton? singleton { get; set; }
// this is private, so can only be accessed from within this class
// there's no public constructor!
private Singleton()
{
// we're constructing a new instance,
// so set the static singleton to this instance
singleton = this;
}
// from the outside, we need to call GetSingleton(), which will instantiate
// the Singleton class ONLY if it hasn't yet been instantiated
public static Singleton GetSingleton()
{
if (singleton != null)
{
return singleton;
}
return new Singleton(name);
}
// of course, the Singleton class actually does something
// so more methods will follow here
}
Using the Singleton pattern in C#
I’ve added an example Singleton pattern in a C# console application project to this GitHub repo. In general, it’s best to let .NET’s dependency injection take care of managing Singletons for you (by using, e.g., AddSingleton<T>()). Another option (that is actually less verbose than my simple example) is to use Lazy<T>(), which has the added benefit of being thread safe and (as the name implies) only instantiates the class / object when needed.
Footnotes
Freeman, Eric & Elisabeth Robson. 2021. Head First Design Patterns: Building Extensible & Maintainable Object-Oriented Software, 2nd Edition. O’Reilly. Page 117. Slightly different wording in Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1994. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley Professional. Page 127. ↩