“There can be only one”

This article was originally published in VSJ, which is now part of Developer Fusion.
Way back in 1986, Christopher Lambert was being immortalised as Connor MacLeod in the cult science-fiction film, Highlander, which is arguably most famous for its tagline that I’ve taken as the title for this article. Interestingly, “there can be only one” is a mantra often heard when developers start discussing design patterns, for the simple reason that it succinctly expresses the intent of the Singleton pattern: the desire to have just one instance of a type when a program runs.

Getting started

The idea of only having a single instance of a type makes a lot of sense under certain circumstances. For instance, you really only want one Find & Replace dialog in Visual Studio; or maybe your design would benefit from having just a single connection pool to talk to a database. Typically, many factory classes are implemented as singletons simply because it is inconvenient to instantiate the factory in order for it to then make the desired objects.

Let’s take a look at an example of where having a singleton makes a reasonable degree of sense: a Web Service load balancer for routing requests from an ASP.NET server to some middle-tier application servers, as shown in Figure 1.

Figure 3
Figure 1: The round-robin load balancer

This load balancer uses a simple “round robin” algorithm, meaning that it will na•vely route the requests to each application server in sequence, regardless of the level of load that the server might be under. The initial code for the balancer can be seen in Listing 1.

The main method of interest here is GetServiceProxy<T>(), which returns a Web Service proxy that has had its Url set to the appropriate server address. These addresses are simply read from a configuration file by an appropriate configuration file section handler (the code for which is not shown as it is not central to the discussion).

Hey. That’s no Singleton!

The ServiceLoadBalancer is certainly no singleton as it’s currently written, with the client usage pattern shown in Listing 2.

The problem with this code is that developers can arbitrarily instantiate new ServiceLoadBalancer objects, which is clearly something that we’d like to prevent. Why? Well, every time you create a ServiceLoadBalancer it will create a proxy whose Url is set to the first server address from the list. Consequently, if the code pattern from Listing 2 is used throughout the application then no balancing will occur, as the client code currently creates and then uses a ServiceLoadBalancer object for each request.

Why not simply make ServiceLoadBalancer a static class?

A quick and easy fix to the object instantiation problem is to make the ServiceLoadBalancer a static class. By definition, static classes cannot be instantiated and all the members have to be marked with the static keyword. This has a number of ramifications, not the least of which is that you wouldn’t be able to extend ServiceLoadBalancer using inheritance.

And I know that this is going to sound fairly strange when discussing a singleton, but there are going to be occasions when you’re going to want to create multiple objects but still control access to the constructor. Therefore, making the class static is unlikely to be a good solution to the problem.

A good example of the fragility of the static class implementation can be seen with the .NET ThreadPool. This is a deeply frustrating class that prevents you from creating your own thread pools. Now, there are many good reasons why you don’t want to allow bazillions of threads, but you can really appreciate the problems that static classes bring when you see, for example, the WCF team implementing their own thread-throttling system because they need to avoid starving ASP.NET of worker threads from the single pool.

ServiceLoadBalancer as a Singleton

The GoF define the intent of the Singleton pattern as follows:
“Ensure a class only has one instance, and provide a global point of access to it.”
The key to making ServiceLoadBalancer a singleton is to deny access to the constructor to any code other than the ServiceLoadBalancer type itself. This is trivially achieved by making it private. With that done it then becomes necessary to provide a publicly accessible method or property for getting hold of the instance that ServiceLoadBalancer will create itself. A revamped ServiceLoadBalancer that supports this is shown in Figure 2.

Figure 2
Figure 2: ServiceLoadBalancer as a singleton

Drilling down into the diagram yields the code as shown in Listing 3.

Client code can no longer instantiate a ServiceLoadBalancer object because the constructor is private, and instead has to use the publicly accessible, static, Instance property to gain access to the single object that is held in the private _instance field.

The client code therefore has to be reworked to that shown in Listing 4.

So, ServiceLoadBalancer is now a Singleton, which means that it must be time to put your feet up, have a cup of tea and admire how simple the Singleton pattern is.

Sadly that’s not the case, as there are a number of subtleties that have to be examined.

Type initialisation and the CLR

Listing 3 declares and initialises the static _instance field in a single statement. However, that’s not the only way to initialise static fields: you can provide a type-initializer, also known as a class constructor, to do the work for you. The code in Listing 5 is identical to that of Listing 3, with one exception: the field is initialised in the type-initialiser (and for reasons that will become clear when you look at Figure 3, the type has been given a different name).

“Big deal,” I hear you cry, “this just looks like you want me to type slightly more code.” There is, however, one tiny difference that you can only see by delving into the MSIL, as shown in Figure 3.

Figure 3
Figure 3: The beforefieldinit attribute

The two types are identical in all aspects apart from one attribute that’s been applied to the original ServiceLoadBalancer implementation: beforefieldinit.

beforefieldinit

So what does the beforefieldinit attribute mean? The ECMA-335 CLI specification describes it as follows (in section 8.9.5):
“The semantics of when and what triggers execution of such type initialization methods, is as follows:
  1. A type can have a type-initializer method, or not.
  2. A type can be specified as having a relaxed semantic for its type-initializer method (for convenience below, we call this relaxed semantic BeforeFieldInit).
  3. If marked BeforeFieldInit then the type’s initializer method is executed at, or sometime before, first access to any static field defined for that type.
  4. If not marked BeforeFieldInit then that type’s initializer method is executed at (i.e., is triggered by):
    • first access to any static field of that type, or
    • first invocation of any static method of that type or
    • first invocation of any constructor for that type.”
You can see the subtle difference in point three. With beforefieldinit applied to the class, the type-initializer can fire pretty much whenever it likes up to and including just before the first access of a static field. This relaxed (even lazy!) initialisation approach can come in handy if you have a relatively expensive object that you want to make as late as possible, but you do need to be aware that the JIT compiler can decide to greedily initialise the type whenever it feels like before the first field access. Thus it might not be lazily initialised after all.

For more information on how beforefieldinit can affect the rules of how and when type initialisation can occur, see section 10.5.3 of the ECMA-335 CLI specification.

The other possible concern that we have with relying on the type-initialiser relates to the issue of exceptions. If an exception is thrown during type initialisation then the CLR doesn’t simply grind to a halt: it retains the exception and then throws a TypeInitializationException each and every time you attempt to access the type.

Consequently, if you want to have more control over initialisation, you might want to roll your own lazy initialiser.

Lazy initialisation of a Singleton

Listing 6 contains an initial attempt at a lazily initialised version of the ServiceLoadBalancer.

As you looked at Listing 6 I hope that a huge alarm rang in your mind. Whereas the CLR will try its absolute best to ensure synchronisation around the type-initialiser, no such rules apply to accessing the static Instance property. Clearly, therefore, there is a potential race condition here should two or more threads simultaneously perform the conditional check, and thus both might execute the construction logic.

This is obviously undesirable behaviour, but can be resolved with a little bit of extra synchronisation work.

Synchronising initialisation

The first (!) attempt at solving the race condition is shown in Listing 7.

We can rest assured that only one thread will now initialise the _instance field, but this comes at a price: every time the client code accesses the Instance property it has to obtain the lock. Arguably this is unnecessary and will adversely affect performance, so you might consider using “double check locking” to ensure that a lock is only taken during initialisation.

The double checked lock version of the code is shown in Listing 8.

In this implementation, the value of the _instance field is checked twice for null (hence the name double check lock). In the rare, but possible, situation that two or more threads are accessing the Instance property at the same time before the _instance field has been initialised, they will hit the lock and thus access to the construction of the singleton is correctly synchronised. However, for all subsequent accesses, the _instance field won’t be null and thus no lock will need to be taken.

You might also have noticed that the keyword volatile has been applied to the _instance field. This helps to ensure that the compiler performs no magical optimisations that prevent the code from re-reading the value of the _instance field after the lock has been obtained.

Unorthodox synchronisation when initialising

There is another, somewhat less common, approach for providing synchronised lazy initialisation: using a nested type. Listing 9 shows an example of this technique.

The fun part here is that we use a nested type which benefits from the same static lazy initialisation that you saw earlier to create the ServiceLoadBalancer object. Thus we utilise the CLR’s protection mechanism around type initialisation without having to write our own double check lock. Note that the code also wraps any TypeInitializationException and re-throws the actual exception, but you should consider this to be optional, especially as it potentially loses some fidelity over where the original exception was thrown.

Apart from the fact that you don’t have to write your own locking code, are there any real benefits to using this approach? Not really, although it is marginally faster than obtaining the lock yourself. However, it does help to reinforce one thing: as soon as you go down the Singleton path, object creation becomes opaque to the client, which means that you can start having real fun.

And what do we mean by real fun?

Well, how about having singletons that have many instances!

Multi-instance Singletons

Intriguingly, when examining the consequences of using the Singleton pattern, the GoF state the following benefit (amongst others):
“Permits a variable number of instances”
A variable number of instances! Surely a singleton should have only one instance? There are actually many occasions where having multiple instances of a Singleton can be a benefit. Here are a couple of examples where this might make sense:
  1. The Singleton consumes resources but hasn’t been used for a while. In this case, it might make sense to destroy the object and then re-create it at a later time if it is used again. This is the approach adopted by .NET Remoting singleton servers, for example.
  2. You want to have a Singleton per-thread, to avoid having to provide synchronisation code within the type’s methods and properties.
The second one of these looks particularly interesting; and it’s also incredibly easy to implement with .NET. Listing 10 is a per-thread implementation of the ServiceLoadBalancer.

By applying the ThreadStaticAttribute to the static _instance field, each thread will get its own copy of the field. This also means that we no longer need to synchronise construction of the object with double check locking. All you have to consider now is whether this is really what you want from a Singleton.

Of course, the key reason that the GoF list the ability to create multiple instances as a beneficial consequence is that no client-side code changes are required if you change the internal implementation of your Singleton to create multiple instances.

Other considerations

Up to now I’ve focused exclusively on the creational aspects of the Singleton pattern, but there are lots of other things to consider. Let’s look at some of them now.

Synchronisation of the object
In by far the majority of cases, you will create Singletons that have only one instance. This means that you must expect multiple threads to access the innards of the object simultaneously, and thus you must add synchronisation code as necessary around fields and other critical resources.

Clients holding long-lived references
You also have no control over clients that hold long-lived references to the object that your accessor method (or Instance property, in our example) returns. Thus, whilst you might decide to “destroy” the object, you might leave a client holding onto something that is present but severely damaged. Of course, destroying an object is pretty much impossible in CLR terms, but you could call its Dispose method (if it has one) and thus leave a somewhat confused client wondering why they get an ObjectDisposedException from a singleton.

Disposable objects
Frustratingly, certain types do offer methods for resource cleanup, such as by implementing IDisposable. And there’s no way of stopping clients from calling them.

Earlier in the article I mentioned the Find & Replace dialog from Visual Studio, which if you were implementing it yourself might make a good candidate for a Singleton. However, the System.Windows.Forms.Form class exposes a public Close method. Once the form has been closed it becomes unusable. There are tricks and techniques that can help with this, including adding checks to see whether a form has been closed (disposed) or not, or by hooking into events such as FormClosing to hide the form instead of actually closing it. An example of this last approach is shown in Listing 11.

Even this implementation is beset with the odd problem, because modeless forms understand the concept of window ownership; there can only ever be one owner of a modeless form at a time. Thus a client that calls FindReplaceForm.Instance.Show(this) might find themselves on the wrong end of an exception if the FindReplaceForm is already visible and owned by another form.

Singletons and AppDomains
A singleton is only a singleton within an AppDomain. This might not be a major drama, but if you were hoping to have a singleton survive ASP.NET AppDomain restarts, for example, then you’re going to be very disappointed.

Testing
Fancy running some unit tests over a Singleton? There’s only one slight problem. You have no control over the lifetime of the object and it thus becomes much harder to test. Similarly, it’s quite tricky to replace a Singleton with a mock object, because it’s difficult for an engine to inject object creation (with that lovely singleton behaviour) into the code.

Inheritance
Ask yourself a simple question: should you be allowed to derive from a Singleton?

Well, it’s problematic at best because the Singleton’s constructor is likely to be private and is therefore inaccessible to the deriving type: hence no derivation is possible, because object construction cannot occur.

Of course, you could make the Singleton’s constructor protected, but then the Singleton would no longer have control over its instance creation and therefore, by definition, would cease to be a Singleton.

Finally, static methods and properties can’t be overridden, which does limit the capabilities somewhat.

“I just gotta get me some of that Singleton magic”

Singleton is a pattern that is very easy to understand. This often means that it is the first pattern that developers learn; which means that they want to head out and implement it, even when they shouldn’t. Singleton’s reputation has thus become somewhat tarnished over the years because developers have used it for tasks such as adding global variables to their programs (shudder), or in situations where it’s completely inappropriate.

Conclusion

Singleton is certainly an interesting pattern. It is easy to understand, although getting the implementation details just right can be harder than it first appears: synchronisation and lifetime management need to be carefully monitored; and testing can be tougher than with a “normal” type.

At the end of the day, Singleton offers you a mechanism to control how and when instances of a type are created. The intent is that you want to constrain the type to a single instance, with a single point of access to it.

However, there are a number of consequences that you have to consider before adopting this pattern. Which brings us neatly back to Highlander: the last thing that you want to do is to lose your head over a design pattern!


Dave Wheeler is a freelance consultant and software author, working primarily with Microsoft .NET. He delivers training courses with DevelopMentor, helps moderate various Microsoft forums, and is a regular speaker at DevWeek and other conferences. Fortunately, there is only one of him! He can be contacted at [email protected].


Listing 1: The na•ve Web Service load balancer

public class ServiceLoadBalancer
{
	string[] serverAddresses;
	int curNode;
	public ServiceLoadBalancer()
	{
		ServerUrlConfigurationSection col
		= ServerUrlConfigurationSection)
			ConfigurationManager.
			GetSection("serverUrls");
		List<string> addresses =
			new List<string>();
		foreach (ServerUrlElement elem
			in col.ServerUrls)
		{
			addresses.Add(elem.Address);
		}
		curNode = -1;
		serverAddresses =
			addresses.ToArray();
	}
	string GetNextServerAddress()
	{
		curNode = ++curNode %
			serverAddresses.Length;
		return serverAddresses[curNode];
	}
	public T GetServiceProxy<T>() where
		T : SoapHttpClientProtocol, new()
	{
		T proxy = new T();
		proxy.Url =
			Regex.Replace(proxy.Url,
		@"http://([\w|:|\d|\.]*)(?=/)",
			GetNextServerAddress());
		return proxy;
	}
}

Listing 2: Using the ServiceLoadBalancer

ServiceLoadBalancer lb =
	new ServiceLoadBalancer();
using(CustomerService proxy = lb.
	GetServiceProxy<CustomerService>())
{
	Customer cust = proxy.
		GetCustomersByCountry("USA");
}

Listing 3: ServiceLoadBalancer as a Singleton

public class ServiceLoadBalancer
{
	private static ServiceLoadBalancer
		_instance = new
		ServiceLoadBalancer();
	public static ServiceLoadBalancer
		Instance
	{
		get {
			return _instance;
		}
	}
	private ServiceLoadBalancer()
	{
		// .ctor implementation is same
		// as for Listing 1
	}
	// rest of class is identical to
	// Listing 1
}

Listing 4: Client code using the Singleton ServiceLoadBalancer

using( CustomerService proxy =
	ServiceLoadBalancer.
	Instance.GetServiceProxy<
	CustomerService>())
{
	...
}

Listing 5: An alternative Singleton implementation

public class
	ServiceLoadBalancerOptionB
{
	private static
		ServiceLoadBalancerOptionB
		_instance;
	static ServiceLoadBalancerOptionB()
	{
		_instance = new
			ServiceLoadBalancerOptionB();
	}
	// Rest of the type is identical
	// to Listing 3
	...
}

Listing 6: Lazy initialisation, cowboy style

public class ServiceLoadBalancer
{
	private static ServiceLoadBalancer
		_instance = null;
	public static ServiceLoadBalancer
		Instance
	{
		get
		{
			if( _instance == null )
				_instance = new
					ServiceLoadBalancer();
			return _instance;
		}
	}
	private ServiceLoadBalancer()
	{
		// .ctor identical to Listing 1
	}
	// Rest of class identical to
	// Listing 1
}

Listing 7: Lazy initialisation with synchronisation

public class ServiceLoadBalancer
{
	private static ServiceLoadBalancer
		_instance = null;
	private static object syncLock =
		new object();
	public static ServiceLoadBalancer
		Instance
	{
		get
		{
			lock( syncLock )
			{
				if( _instance == null )
					_instance = new
					ServiceLoadBalancer();
			}
			return _instance;
		}
	}
	private ServiceLoadBalancer()
	{
		// .ctor identical to Listing 1
	}
	// Rest of class identical to
	// Listing 1
}

Listing 8: Using a double check lock

public class ServiceLoadBalancer
{
	private static volatile
		ServiceLoadBalancer _instance
		= null;
	private static object syncLock =
		new object();
	public static ServiceLoadBalancer
		Instance
	{
		get
		{
			if( _instance == null )
			{
				lock( syncLock )
				{
					if (_instance == null)
						_instance = new
					ServiceLoadBalancer();
				}
			}
			return _instance;
		}
	}
	// rest of code as before
	...
}

Listing 9: Synchronised lazy initialisation with nested types

public class ServiceLoadBalancer
{
	public static ServiceLoadBalancer
		Instance
	{
		get
		{
			try
			{
				return
				InstanceCreator.Instance;
			}
			catch(
		TypeInitializationException exn )
			{
				throw exn.InnerException;
			}
		}
	}
	private class InstanceCreator
	{
		private static
			ServiceLoadBalancer _instance
			= new ServiceLoadBalancer();
		public static ServiceLoadBalancer
			Instance
		{
			get
			{
				return _instance;
			}
		}
	}
	// rest of ServiceLoadBalancer code
	// as before
}

Listing 10: A per-thread Singleton

public class ServiceLoadBalancer
{
	[ThreadStatic]
	private static ServiceLoadBalancer
		_instance;
	public static ServiceLoadBalancer
		Instance
	{
		get
		{
			if( _instance == null )
				_instance = new
				ServiceLoadBalancer();
			return _instance;		
		}
	}
	private ServiceLoadBalancer()
	{
		...
	}
	...
}

Listing 11: A Singleton Windows Forms

public partial class FindReplaceForm
	: Form
{
	// No thread-safety because we
	// assume STA!
	private static FindReplaceForm
	_instance = new FindReplaceForm();
	public static FindReplaceForm
		Instance
	{
		get
		{
			return _instance;
		}
	}
		private FindReplaceForm()
	{
		InitializeComponent();
	}
	protected override void
OnFormClosing(FormClosingEventArgs e)
	{
		base.OnFormClosing(e);
		// Hide the form if it is being
		// closed by the user or by
		// client code that is calling
		// Close()
		if( e.CloseReason ==
			CloseReason.UserClosing )
		{
			this.Hide();
			e.Cancel = true;
		}
	}
}

You might also like...

Comments

About the author

Dave Wheeler United Kingdom

Dave Wheeler is a freelance instructor and consultant who specialises in .NET application development. He’s a moderator on Microsoft’s ASP.NET and Silverlight forums and is a regular speaker at ...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“Owning a computer without programming is like having a kitchen and using only the microwave oven” - Charles Petzold