Generic and Threadsafe Singleton Implementation
February 6th, 2006
I googled around, and couldn’t find a generic singleton implementation that was 1) correct and 2) met all of my needs. This is a clever approach, but unfortunately it is limited to objects that are created by calls to constructors.
So I went ahead and wrote the singleton generic that I fully expect to be included in the next BCL. (Not really. It’s completely straightforward. However, the Steelers won the super bowl yesterday, so I’m not really in a modest mood.)
I started out defining a class factory type, which is responsible for creating the an instance in a purposefully vague way. I also wrote the default version which just calls new().

/// <summary>
/// Interface for objects that create instances of
/// another type.
/// </summary>
public interface IClassFactory<T> where T : class
{
T CreateInstance();
}
/// <summary>
/// A default <see cref="IClassFactory"/> implementation,
/// which uses a parameterless constructor to create the
/// instance.
/// </summary>
public class DefaultClassFactory<T> : IClassFactory<T>
where T : class, new()
{
public T CreateInstance()
{
return new T();
}
}
From there, I went for the slam dunk in writing both a singleton class with a class factory and a default version that doesn’t require one.

/// <summary>
/// A base (or helper) singleton class. Defines the
/// singleton instance.
/// </summary>
/// <typeparam name="T">
/// The type of the singleton object.
/// </typeparam>
/// <typeparam name="class_factory">
/// The type of the class factory to use to create an
/// instance of type <typeparamref name="T"/>.
/// </typeparam>
public class Singleton<T, class_factory>
where T : class
where class_factory : IClassFactory<T>, new()
{
private static object _sync = new object();
private static T _default;
/// <summary>
/// Gets the singleton instance.
/// </summary>
public static T Default
{
get
{
EnsureDefault();
return _default;
}
}
/// <summary>
/// Ensures that the singleton has been created.
/// </summary>
private static void EnsureDefault()
{
if (_default == null)
{
lock (_sync)
{
if (_default == null)
{
CreateDefault();
}
}
}
}
/// <summary>
/// Uses the class factory to create the instance.
/// </summary>
private static void CreateDefault()
{
class_factory cf = new class_factory();
T value = cf.CreateInstance();
// This ensures that writes in the creation of
// the default instance won't be shuffled beyond
// the write to _default. Only matters on multiproc
// machines where the hardware allows this. Does
// nothing on an x86.
Thread.MemoryBarrier();
_default = value;
}
}
/// <summary>
/// A basic singleton type that can be used with objects
/// that are created with a parameterless constructor.
/// </summary>
public class Singleton<T> :
Singleton<T, DefaultClassFactory<T>>
where T : class, new()
{
}
(For more on why I added that call to Thread.MemoryBarrier(), see this writeup.)
Here’s a really simple example that does not take advantage of the customizability:
public class Foo : Singleton<Foo>
{
}
If you can’t use Singleton as a base class, you have to write a little more code.
public class Foo : Bar
{
public static Foo Default
{
get { return Singleton<Foo>.Default; }
}
}