Singleton in C#

Tuesday, April 6, 2010

The Singleton pattern is one of the most widely used in object oriented programming. The basic idea is to prevent multiple instances of a class. One might ask – how does this differ from a static class?

Difference between a Static class and a Singleton

Static classes are used whenever there is no reason to associate an identity with an object. For example – if one were modeling a Financial Application, a class representing Money (containing numeric conversion methods etc.) could be designed as static. There is no really good reason to pass instances of the Money class around. All one needs is one single object representing Money and it is not tied to an identity (there isn’t a Money1 and a Money2 for two different end users). However – an object representing the Account for the same two users – does require an identity. Each account would need to be tied to a unique user – hence we would need independent instances of the Account object.  Static would not be a good choice for the Account class.

There are several other differences between static classes and regular instantiable classes. One of the other driving factors is whether we need to determine something at runtime. Say – our object – on loading up – needed to determine the type of the operating system (OSType). A static class needs to know everything at compile time – so it would not be a good choice for this runtime need of ours. A good overview of some of the reasons to use a static class can be found on MSDN.

It also helps to remember that a static class is never actually instantiated.

While we have discussed when to use a static class versus instances, we haven’t yet discussed when to use singletons versus static classes.

There is one school of thought that says – never use a singleton – and another that says – avoid static classes altogether. Personally, I belong to the latter school of thought.

Here are a few reasons I believe that static classes can be replaced with equivalent Singletons:

  1. Multiple Instances; In case you want more than one instance down the road. With a Singleton, you always retain the flexibility of modifying the class to (to create more than one instance) later – without affecting any consumers of the class. With a static class, you can do the same thing but only at the cost of breaking (modifying) all consumers.
  2. Initialization: A static class is always initialized right away (at compile time). There is no flexibility in when or how it is to be initialized (there is a static constructor in c# – but it is nothing more than a compile time initialization method). With a Singleton, you have control over when to initialize it. Using lazy Ioading, a singleton can be initialized only when it is needed.
  3. State: Holding state – If you need a centralized place to hold stateful information (for e.g. a Visitor Count Tracker on your website), a Singleton is a good choice.

We have discussed some of the reasons why an instance class (implemented as a single instance i.e. a Singleton) offers more power and flexibility than a Static class. More generally, the difference between static classes based programs and instances (objects) based applications lies at the heart of the difference between procedural programming and Object Oriented programming.

So – we have concluded that we do need an identity based class, which is capable of holding state and which can be possibly modified down the road to return more than one instance. For now though, we are only interested in a single instance.

The Singleton Pattern

The code below demonstrates the basic Singleton pattern. 

Code Discussion

  1. Line 3: Static field to hold the singleton: Since we need to create the singleton one time only, we use a static field to hold it (notice that this is different from using a static class – all we are doing is having a static field inside a regular class).
  2. Note also that there is no constructor – since no one is allowed to create instances of this class. 
  3. Line 6: The Singleton class does a simple check on itself to see if it exists (pretty existential if you ask me). If it doesn’t, it creates itself this one time only – so that it will always find itself in future checks.
Code Snippet
  1. public class Singleton
  2. {
  3.   public static Singleton Instance  = null;  
  4.   public static Singleton CreateInstance()
  5.   {
  6.     if(Instance == null)
  7.       Instance = new Singleton();
  8.  
  9.      return Instance;
  10.    }
  11. }

What can go wrong?

Concurrent Access: The first potential problem is the same problem that affects multiple contention of a single resource – concurrency. You may wonder how it affects this simple class with barely 8 lines of code.

Consider thread1 and thread2 calling the method CreateInstance().

Consider thread1 on line 6 has just finished checking if instance is null. It sees instance as null. Before it can create the new Singleton, it gets pre-empted by a clock tick. Now thread2 comes along and goes through the entire method – including the Instance = new Singleton(). So far all looks good. Until Thread1 returns. Remember that Thread1  still thinks that instance is null since that was the last thing it executed. So – it goes ahead and creates yet another instance ! All of a sudden, our simple class that only wanted to create itself once – has found itself created twice!

This is a common problem in multi-threaded applications and there are several simple workarounds for it. The most common one involves locking. Locking a resource is equivalent to saying that whenever we have multiple consumers vying for that resource, we are going to put them all in a line (serialize them). It effectively serializes simultaneous (parallel) requests.

Workaround 1 -  Use a Lock

Code Snippet
  1. public class SingletonWithLocking
  2.     {
  3.         static object locker = new object();
  4.         public static Singleton Instance  = null;  
  5.         public static Singleton CreateInstance()
  6.         {
  7.           lock (locker)
  8.           {
  9.               if (Instance == null)
  10.                   Instance = new Singleton();
  11.           }
  12.          return Instance;
  13.         }
  14.     }

 

Code Discussion

  1. Line 3: Declare a simple object called locker. This will act as the lock on the lines of code that are sensitive to concurrent access.
  2. Line 7: In C#, this is how you lock a segment of code. Simply use the lock keyword with the locking object (locker) surrounding the sensitive code.

Workaround 2 -  Use a Static Initializer

Code Snippet
  1. /// <summary>
  2.     /// This is the safest and fastest way to design a singleton
  3.     /// </summary>
  4.     public class StaticInitializerSingleton
  5.     {
  6.         // Instead of initializing to null, initialize to the new Singleton
  7.         // public static Singleton Instance = null;
  8.         public static Singleton Instance = new Singleton();
  9.  
  10.         public static Singleton CreateInstance()
  11.         {
  12.             if (Instance == null)
  13.                 Instance = new Singleton();
  14.  
  15.             return Instance;
  16.         }
  17.     }

Code Discussion

Line 8: Instead of initializing to null as we did in our first example, we initialize it to the new Singleton object. This way, we will never have the contention issue on Line 12 (if instance == null), like we did before. This is the simplest and fastest implementation of a Singleton in C# (locking is safe too – but it has an overhead associated with it).

Summary

The Singleton pattern is one of the most oft used patterns in applications today. People tend to confuse static classes with Singletons. This article clarifies the differences between the two. People also use the Singleton shown in example 1 most frequently. This can cause contention issues – since a Singleton, by its very nature, is a single resource – accessed by multiple clients.

Tags:
Filed Under: