February 26, 2013

Singleton pattern

Singleton is using when you need a class that has only one instance, and you need to provide a global point of access to the instance. As you can notice, singleton is similar to the global variable. And as the global variable it can violates testability and scalability of your system. So you should use it carefully or not to use at all if you can. But if you need it, you can use this 'lazy' implementation. ('Lazy' means that the instantiation is not performed until an object asks for an instance, whereas global variables always consume resources when the application starts):
using System;

public class Singleton
{
   private static Singleton instance;

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}
Looks pretty easy. But this way singleton can have a successor, that may introduce unwelcome dependencies sometimes. To prevent derivation let's mark the class sealed:
public sealed class Singleton 
{
   private static readonly Singleton instance = new Singleton();
   
   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         return instance; 
      }
   }
}
Here we still have 'lazy' implementation. The Singleton instance is referenced by a private static member variable, thus the instantiation does not occur until the class is first referenced by a call to the Instance property. In addition, the variable is marked readonly, which means that it can be assigned only during static initialization or in a class constructor.

The main disadvantage of these implementations, is that they are 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.
The following implementation allows only a single thread to enter the critical area, which the lock block identifies, when no instance of Singleton has yet been created:
using System;

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;
      }
   }
}
The bottom line: generally singletons are not preferred to use. However it's better than the global vars, because they don't pollute the global namespace with unnecessary variables and also permit lazy allocation and initialization.