Generic Singleton Provider






4.79/5 (20 votes)
Jul 26, 2005
2 min read

149690

1
An article describing how to use Generics to create a singleton provider.
Introduction
Many people from different programming backgrounds should be familiar with the Singleton Pattern. Those who use it will find that they often have to write the same code each time they want to create a different Singleton class. With the advent of C# 2.0 Generics, it is possible to write this code only once.
Background
There are many articles about the Singleton Pattern. Probably the most comprehensive one for C# can be found here: "Implementing the Singleton Pattern in C#".
There is an increasing amount written about C# Generics. For example, a CodeProject article can be found here: "Generics in C# 2.0" by Ansil.
Using C# 2.0 Generics to achieve a reusable Singleton pattern
Using C# 2.0 Generics, it is possible to create what I have called a 'Singleton Provider'. This is a class that can be used repeatedly to instantiate a class as a singleton without having to re-write the singleton pattern code for that specific class. This has the added benefit of separating singleton code from the class code leaving the flexibility to use several instances of the class or using the class as a singleton.
The singleton code used in this example is based on the fifth example described in the above article about implementing the Singleton Pattern in C#:
public sealed class Singleton
{
Singleton()
{
}
public static Singleton Instance
{
get
{
return SingletonCreator.instance;
}
}
class SingletonCreator
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
With an understanding of Generics, you can see that there should be no reason to replace the type arguments in this block of code with the typical 'T
' found in Generics. If this is done, the code looks like this.
public class SingletonProvider <T> where T:new()
{
SingletonProvider() {}
public static T Instance
{
get { return SingletonCreator.instance; }
}
class SingletonCreator
{
static SingletonCreator() { }
internal static readonly T instance = new T();
}
}
Note that the Generics must have a constraint on it. This constraint forces any type 'T
' to have a default constructor, that is, a constructor that takes no parameters. This allows the SingletonCreator
to instantiate the type 'T
'.
So, how does one use the SingletonProvider
? To understand how to use this, we need a test class. The test class has two features. The first is a default constructor that sets a timestamp member variable. The second is a public method that writes that timestamp using Debug.WriteLine
. This setup means that no matter which thread uses this class in the Singleton Pattern, whenever that public method is called, it should output the same value.
public class TestClass
{
private string _createdTimestamp;
public TestClass ()
{
_createdTimestamp = DateTime.Now.ToString();
}
public void Write()
{
Debug.WriteLine(_createdTimestamp);
}
}
The class is used with the SingletonProvider
as follows:
SingletonProvider<TestClass>.Instance.Write();
Points of Interest
I have tested this code with a Dual Processor with hyper-threading enabled with 100 threads accessing the singleton. They all output the same value illustrating that this is a thread-safe generic way to create singletons.
I believe that this is a really neat illustration of how Generics can save you writing code.
History
This is the first iteration of this code, please provide any feedback as to whether you have used this or not or any problems that anyone has found with it!