This is the third post of a series on the Service Locator pattern. In the first post I described how to create a basic service locator for your C# application, while in the second post I introduced lazy initialization of the services.
We now add another piece to our puzzle, transforming the Service Locator class into a singleton.
The Singleton Pattern
The singleton is arguably the most known and controversial design pattern. Some say singletons are good, some says singletons are evil. Eric Gamma himself (one of the Gang Of Four) in a recent interview stated that (emphasis added):
When discussing which patterns to drop, we found that we still love them all. (Not really—I'm in favor of dropping Singleton. Its use is almost always a design smell.)
I don't have a strong opinion either way; I tend to use it sparingly and in the following code I will show how to apply this pattern to the service locator. There are already countless blogs discussing the pros and the cons of the singleton pattern, therefore I won't discuss about it any further.
The Singleton Service Locator
The following was our initial implementation (other details of the classes have been removed for clarity). The constructor was internal, allowing all potential clients from within the assembly to invoke it. Clients could either pass around a reference to the created service locator, or instantiate new instances each time:
To implement the singleton pattern, we make the constructor private and provide clients with a static method through which we can retrieve an instance of the service.
Note how the creation of the single instance of the ServiceLocator class is itself lazy and thread safe. There are a few variations on the theme when it comes to singleton thread safe initialization (see for example this post by Jon Skeet).
Clients will now simply invoke the
GetService() method through the singleton instance, without having to create a new object each time: