EPiWiki.se  - EPiServer notes shared with others
 

Implementing singleton pattern

[Edit]
Implementing a singleton in C# is probably harder than you think, because it has to be high performance, thread safe and lazy loaded (so the instance isn’t loaded before it is used).

Singleton pattern for best performance (recommended for most implementations)



// The class can’t be inherit so mark it sealed
public sealed class Singleton
{
    // Don’t use any static constructor sense it will mark the class
    // with beforefieldinit, and the JIT has to check if the constructor is
    // called for each request to static methods.

    // Set the instance in the static constructor to make a
    // thread safe initialization and mark the instance read only
    // for increase performance
    static readonly Singleton instance = new Singleton();

    // Set the default constructor to be private so it not possible to
    // to create a own instance of the class
    private Singleton(){ }

    public static Singleton Instance { get { return instance; } }
}

Singleton pattern - lazy loaded (not recomended but needed sometimes)



// The class can’t be inherit so mark it sealed
public sealed class Singleton
{
    // Set the default constructor to be private so it not possible to
    // to create a own instance of the class
    private Singleton() { }

    public static Singleton Instance { get { return SingeltonImplementation.instance; }}
        
    class SingeltonImplementation
    {
        // Let the compiler mark the class beforefieldinit so it’s lazy
        // initialized
        static SingeltonImplementation () { }

        // Set the instance in the static constructor to make a
        // thread safe initialization and mark the instance read only
        // for increase performance
        internal static readonly Singleton instance = new Singleton();
    }
}

Remarks


The empty static constructor removes the attribute beforefieldinit (if you look at the IL codefor the class) that let the runtime make the initialization of the static fields in the class lazy loaded so we don’t allocate the instance before we want to use it. This means that the JIT compiler has to evaluate if the static fields has been initialized before each call to any static method and will decrease performance.

IL code when using a static constructor



.class public auto ansi sealed Singleton
    extends [mscorlib]System.Object

IL code when NOT using a static constructor



.class public auto ansi sealed beforefieldinit Singleton
    extends [mscorlib]System.Object


Version author:
Mattias Lövström

EPiServer version

All