Post

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

  1. 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. 

This post is licensed under CC BY 4.0 by the author.