The Singleton Pattern

We hear about "Design patterns" all the time. We, as programmers, are trained to obey design patterns, and that design patterns are king, and that we should never deviate from them.

In some cases, especially for the simpler patterns (such as the Singleton pattern), there's really not much deviation you can perform. In some other cases, however, there's a lot of interpretation (and unfortunately, religious wars) surrounding the use of them.

Every now and then in this column I'm going to pick on one and give a bit of a lowdown on it, starting with this article on the Singleton.

What Is a Singleton?

Exactly as the name implies, a "Singleton" is an object that always presents the same instance, irrespective of how it's created and by what.

In a web application, for example, you might have a queue driver that's a singleton, so that every time you push some data to it, you know that you're pushing to the same queue.

Some developers use singletons to provide a unified data interface, or a web kiosk may use a singleton to ensure a web application has access to a credit card reader to establish that it can do multipart credit card transactions.

It's useful because, in our world of multi tenancy, multi stage, stateless web applications, we know that employing a singleton means that we are able in some small part to have a central area where we can be sure the underlying functionality remains constant.

A session state manager, for example, would be a good candidate. It would allow you to push login information into a session, and then retrieve that even on a completely different request.

How Does a Singleton Work?

Very easily.

It's a simple case of using a static factory or abstract factory to build an instance of the object you want to have as a singleton.

Using a full factory to build it, however, is usually a bit of an overkill, so you would normally just have a static accessor in the actual singleton object itself, that acts as a factory interface.

The process to instantiate a singleton would typically go something like this:

  1. The client requests a new instance of the object by calling a static function in the object itself.
  2. The object will look at its internal state and determine if it has an active container already allocated.
  3. If it does not have an allocation, a new allocation will be created internally and returned to the client.
  4. If it does have an allocation, the existing allocation will be returned to the client.

Implementing the Singleton in C#

Please note, I will not be using any dependency injection containers here. My intention is to show how the pattern works, not how to use it in TinyIOC/Windsor/Ninject etc., etc.

Start by creating yourself a simple command line program in Visual Studio.

Once you have a standard static program available, add a class to your project. Call this class "MySingleton".

Make sure the code in your class looks like the following:

namespace Singleton_Pattern
{
   public class MySingleton
   {
      public string SomeText { get; set; }

   }
}

Remember to adjust namespaces and class names as required if you've used different ones.

If you now make your main program look as follows:

using System;

namespace Singleton_Pattern
{
   class Program
   {
      static void Main()
      {
         MySingleton testOne = new MySingleton();
         testOne.SomeText = "Hello World";

         MySingleton testTwo = new MySingleton();
         testTwo.SomeText = "Hello Earth";

         Console.WriteLine(testOne.SomeText);
         Console.WriteLine(testTwo.SomeText);

      }

   }
}

You'll see that we have a normal (non singleton) class set-up.

We know that each class is fully independent of the other, because changing the text in one does not change it in the other, as you'll see if you press F5 to run it:

Single1
Figure 1: The screen displays the text from the previous code

To turn our class into a singleton, we need to ensure that whenever we access an instance, we always get the same instance available. The actual meat and bones of our class (Properties, Methods, and such) need to be created in an internal class, with our "MySingleton" class wrapping it for access.

Update your MySingleton class so that it now looks like this:

namespace Singleton_Pattern
{
   public class MySingleton
   {

      private static MySingleton instance;

      private MySingleton() { }

      public static MySingleton Instance
      {
         get { return instance ?? (instance =
            new MySingleton()); }
      }

      public string SomeText { get; set; }

   }
}

If you look back at your program, you'll now see that the code is showing as being in error:

Single2
Figure 2: Errors have appeared

If you hover over one of the errors, you'll see that you can now no longer "new up" an instance of your class, because we've made the constructor private:

Single3
Figure 3: The error's source is disclosed

To get a new instance of or "MySingleton" class, we now instead of "newing it" need to access it by using the static instance method.

If we change our program code to this:

using System;

namespace Singleton_Pattern
{
   class Program
   {
      static void Main()
      {
         MySingleton testOne = MySingleton.Instance;
         testOne.SomeText = "Hello World";

         MySingleton testTwo = MySingleton.Instance;
         testTwo.SomeText = "Hello Earth";

         Console.WriteLine(testOne.SomeText);
         Console.WriteLine(testTwo.SomeText);

      }

   }
}

You'll see that our errors will go away, and we can, once again, use our MySingleton class.

If you run the program now, however, you'll see a different output than you did previously.

Single4
Figure 4: Changing the code has changed the output

As you can see, when you changed the text in the second instance, you changed the text in the first instance.

In the "testOne" object, no instance of your "MySingleton" class existed, so the internal mechanics created one and made it available to you.

When "testTwo" was allocated, however, an internal instance already existed, so that was returned.

As a result, setting the "someText" parameter meant that we overwrote the value that instance one placed in there, further proof that the exact same instance was being used.

The method we've employed here is called a "Lazy Singleton" and it's not without its dangers. Using a "Lazy Singleton" is really not suitable for concurrent processing systems where multiple threads may be accessing the class at the same time.

It's very possible that two threads could hit the code for the singleton check and creation at exactly the same time, and end up with two separate singleton objects. This would defeat the purpose of having a singleton in the first place.

C#, however, has another way to build this instance, and make it a little more resilient to this scenario.

Change your "MySingleton" class so that it looks as follows:

namespace Singleton_Pattern
{
   public sealed class MySingleton
   {
      private static readonly MySingleton _instance =
         new MySingleton();

      private MySingleton() { }

      public static MySingleton Instance
      {
         get
         {
            return _instance;
         }
      }

      public string SomeText { get; set; }

   }
}

This is not much different to the previous version, but now we're leaving the .NET runtime to create the internal instance. This is more robust (although not still without its problems) than letting a client of the object run the risk of creating multiple versions.

Run the program, and observe that your output is the same as the previous run, confirming that everything is running the same way.

There are a few edge cases where you might still have problems using version 2 of the singleton, and although in about 95% of usages version 2 will suffice, you may occasionally need to go the extra length, and start locking sections of the class while you access them.

If you feel you need to implement this, you simply need to go back to the version 1 way of creating the singleton, but instead of allowing it to run away with itself, you need to add a thread safe lock in the instance creation method to ensure single access is maintained. The code to do that is as follows:

using System;

namespace Singleton_Pattern
{
   public sealed class Singleton
   {
      private static volatile Singleton _instance;
      private static readonly object _syncRoot =
         new Object();

      private Singleton() { }

      public static Singleton Instance
      {
         get
         {
            if (_instance != null) return _instance;
            lock (_syncRoot)
            {
               if (_instance == null)
               _instance = new Singleton();
            }

            return _instance;
         }
      }

      public string SomeText { get; set; }

   }
}

Again, you can verify it works as expected by pressing F5 to run your program, and you should see "Hello Earth" displayed twice as you did previously. Now, however, if multiple threads hit your object, only one access at a time is allowed into the instance allocation routine.

Want to know something about .NET or found a strange API call you want to know how to use? Come find me on the interwebs, usually using the alias 'shawty_ds'. If I like your question, I'll turn it into a post for this column.



Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date