Jelle Druyts .NET Consultant
Just another ignorant weirdo from Antwerp, Belgium trying to make sense out of it all
The Singleton design pattern is one of the most widely known patterns in the software industry. In .NET 2.0, it's easy to provide a generic implementation of this pattern so you won't ever have to write the code that makes it happen again. Even though there's not much code involved, it can be tricky to get right if you consider thread safety and laziness of instantiation.
If you use the class below, accessing a singleton of any class is as simple as calling Singleton<Foo>.Instance. The Foo type only needs to support a default constructor and never worry about the details of the singleton itself. Here's the implementation of the generic Singleton class:
Singleton<Foo>.Instance
Foo
Singleton
/// <summary> /// Provides a global point of access to a single instance of a given class. /// </summary> /// <typeparam name="T">The type to provide a singleton instance for.</typeparam> /// <remarks> /// <para> /// The singleton instance can be accessed through a static property, /// where the type of the singleton is passed as a generic type parameter. /// Subsequent requests for the instance will yield the same class instance. /// </para> /// <note> /// The singleton is thread-safe and lazy (i.e. it is created when the instance /// is first requested). /// </note> /// </remarks> /// <example> /// The following example gets a singleton instance of a <c>Foo</c> class: /// <code> /// Foo singleInstance = Singleton<Foo>.Instance; /// </code> /// </example> public static class Singleton<T> where T : new() { /// <summary> /// Gets the singleton instance. /// </summary> public static T Instance { get { // Thread safe, lazy implementation of the singleton pattern. // See http://www.yoda.arachsys.com/csharp/singleton.html // for the full story. return SingletonInternal.instance; } } private class SingletonInternal { // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit. static SingletonInternal() { } internal static readonly T instance = new T(); } }
Note the implementation using a private class with an explicit static constructor, this is to provide both the thread safety as the lazy instantiation. More details can be found in the "Implementing the Singleton Pattern in C#" article by Jon Skeet.