Tuesday, 20 November 2012

Implementing Singleton in C#


Even though Singleton is a comparatively simple pattern, there are various tradeoffs and options, depending upon the implementation. 

Initial thought - 1st Implementation
     
    public class Singleton
    {
        private static Singleton instance;
        private Singleton() { }
        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }

Advantages:
Because the instance is created inside the Instance property method, the class can exercise additional functionality (for example, instantiating a subclass), even though it may introduce unwelcome dependencies.

The instantiation is not performed until an object asks for an instance; this approach is referred to as lazy instantiation. Lazy instantiation avoids instantiating unnecessary singletons when the application starts.

Disadvantage:
It is not safe for multithreaded environments. If separate threads of execution enter the Instance property method at the same time, more that one instance of the Singleton object may be created. Each thread could execute the following statement and decide that a new instance has to be created:

if (instance == null) 

Next Approach solve this problem. 

Static Initialization – 2nd Implementation
     
    public sealed class Singleton
    {
        private static readonly Singleton instance = new Singleton();
        private Singleton() { }
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
    }
 
In this strategy, the instance is created the first time any member of the class is referenced. The common language runtime takes care of the variable initialization. In addition, the variable is marked readonly, which means that it can be assigned only during static initialization (which is shown here) or in a class constructor.
The only potential downside of this approach is that you have less control over the mechanics of the instantiation. 

Multithreaded Singleton – 3rd Implemenation 
 
This approach is extension of 1st impl to make is thread safe; coz its impossible to overcome the limitation of 2nd impl of - less control on the instantiation.
     
    public sealed class Singleton
    {
        private static volatile Singleton instance;
        private static object syncRoot = new Object();
        private Singleton() { }
        public static Singleton Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new Singleton();
                    }
                }
                return instance;
            }
        }
    }
This approach ensures that only one instance is created and only when the instance is needed. Also, the variable is declared to be volatile to ensure that assignment to the instance variable completes before the instance variable can be accessed. Lastly, this approach uses a syncRoot instance to lock on, rather than locking on the type itself, to avoid deadlocks.