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().

IClassFactory


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

Singleton


    /// <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; }
    }
}