I have been wanting to revisit some design patterns for a while, this has been more urgent recently as my posts have taken on a more philosophical leaning with very little or no code.

I talked about the Singleton pattern many moons ago but over the years I have changed my mind about the best approach multiple times, that along with significant CLR improvements have ensured that I a few new ways to do this. For example the first time I discussed this I never even considered static initializers! The way they work in .NET is that only one thread can be in a static initializer. This means that the .NET framework interprets your use of a static initializer as a queue to implement locking, mutex and volatile variable assignments. I would propose that in almost all use cases the CLR will do a better job than we will. So there is this:

public class SomeSingleton
{
    private static readonly SomeSingleton instance = new SomeSingleton();

    private SomeSingleton()
    {
    }

    public SomeSingleton Instance { get { return instance; } }

    public void SomeThreadSafeWorkToDo()
    {
    }
}

I did reject a similar option earlier because I actually wanted to do Lazy initialization, but what I did not know was that the simple introduction of an empty static constructor alters when the framework is allowed to initialize static variables in the class. In the following example the private static instance variable will only be initialized when it is first used (via the public property) and not when the class is declared.

public class SomeSingleton
{
    private static readonly SomeSingleton instance = new SomeSingleton();

    /// Ensures lazy construction
    static SomeSingleton() { }

    private SomeSingleton() { }

    public SomeSingleton Instance { get { return instance; } }

    public void SomeThreadSafeWorkToDo()
    {
    }
}

Let's ramp up the laziness to 11 just for a moment, because if you think about it calling any other static method of SomeSingleton could inadvertently force SomeSingleton to be prematurely constructed. To plunge down to this kind of lazy we should only be instantiated when you are actively using the public Instance property. So check this out:

public class SomeSingleton
{
    /// Ensures really lazy construction
    private static class SingletonContainer
    {
        internal static readonly SomeSingleton instance = new SomeSingleton();
        static SingletonContainer() { }
    }

    private SomeSingleton() { }

    public SomeSingleton Instance { get { return SingletonConstructor.instance; } }

    public void SomeThreadSafeWorkToDo()
    {
    }
}

Admittedly I have not seen this used very often but it can be helpful to take advantage of private classes nested within another class because the accessibility rules allows SingletonContainer to call the private constructor of SomeSingleton. To be sure this has ramped up the complexity and if you have no other static methods that could cause your singleton to be prematurely created feel free to ignore the above approach.

Lazy in .NET 4

I seemed to have spent much longer on Lazy initialization rather than the singleton pattern, but I thought it important to finally note that .NET now explicitly supports Lazy loading and so this actually becomes are more succinct rewrite. Unlike the previous nested class example it expresses much more directly what I am trying to accomplish.

public class SomeSingleton
{
    private static readonly Lazy lazy = 
                new Lazy(() => new SomeSingleton(), true);

    private SomeSingleton() { }

    public SomeSingleton Instance { get { return lazy.Value; } }

    public void SomeThreadSafeWorkToDo()
    {
    }
}

I included prior .NET option because I am constantly switching between .NET versions at work, and so I assume others are too. To be clear though this last option is the one I lean in to since the release of .NET 4.



Comment Section

Comments are closed.