I have been using the Service Locator pattern for years and I think it has a place in some circumstances – I’ll explain what I mean by that in a minute but first for some scene setting…
If you’re not familiar with the Service Locator then the following shows a simple class diagram that depicts its use:

The following descrription of what the Service Locator pattern is, is detailed here from Wikipedia:
The service locator pattern is a design pattern used in software development to
encapsulate the processes involved in obtaining a service with a strong abstraction layer. This pattern uses a central registry known as the “service
locator” which on request returns the information necessary to perform a certain task
Often the Service Locator is used in conjunction with other patterns such as IoC and DI. (self promotion here, I’ve put together a IoC/DI container with support for event aggregation for Silverlight on Windows Phone : http://wp7.codeplex.com)
If you are a Microsoft shop, then the Common Service Locator is a very popular implementation of this pattern. You can download the code here (by the patterns & practices team at Microsoft): http://commonservicelocator.codeplex.com/
In fact the above website contains some providers for popular Inversion of Control containers such as StructureMap, Unity, Castle Windsor and so on.
Anyway back to the point of this post, when should you implement a Service Locator and is it an anti-pattern? According to this post and many others it is an anti-pattern. My view to that question is it is an anti-pattern if used in the wrong way. The example given in the above post is an anti-pattern because the benefits of IoC are not realised due to lack of understanding in IoC – I see this a lot in enterprise. In fact you can use a vanilla IoC container as a service locator (kind of) it’s more of a factory than service locator but bear with me.
Here is an example of a good use of IoC and DI – to which many of you reading this will already be doing today and will continue to do in the future:
public class Foobar : IFoobar
{
private readonly IFoobarAdapter _adapter;
private readonly IFoobarAdapter2 _adapter2;
public Foobar(IFoobarAdapter adapter, IFoobarAdapter2 adapter2)
{
_adapter = adapter;
_adapter2 = adapter2;
}
public void DoStuffWithAdapters()
{
//...
}
}
Now the above code is nothing new, we are using IoC and DI to abstract dependencies which thus enables us to write good software code that is easilly testable and maintainable. There is no requirement for Service Locator here. The code also tells any human or software program to generate some metrics as to how coupled or otherwise loosely coupled our software might or might not be. So the above, NDepend (my tool of choice for metrics) can easilly figure out the dependencies between class Foobar and the adpaters (interfaces).
Now what if we introduced the Service Locator pattern to the mix here. Consider the following changes to the above Foobar class that now uses Microsofts IServiceLocator:
public class Foobar : IFoobar
{
private readonly IFoobarAdapter _adapter;
private readonly IFoobarAdapter2 _adapter2;
private readonly IServiceLocator _serviceLocator;
public Foobar(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
_adapter = serviceLocator.GetInstance<IFoobarAdapter>();
_adapter2 = serviceLocator.GetInstance<IFoobarAdapter2>();
}
public void DoStuffWithAdapters()
{
//...
}
}
So what’s happening here, and why is the new code not so good? but more importantly, why would you use Service Locator as it seems to be complicating things somewhat…
Firstly, the code is not so good for the following reasons:
- In order to test this class, I’m going to have to new up a IServiceLocator type and ensure it responds to GetInstance for types IFoobarAdapter and IFoobarAdapter2. I know I can use mocking tools like Rhino Mocks here, but I’m just giving myself more work and I’m not getting anything from that change.
- It gives any human and tool such as NDepend an artificial view of the actual coupling between the layers.
By the way it’s worth pointing out here that I can’t remember whether Microsofts implementation of IServiceLocator includes generics. I think I might have added the generic GetInstance to the interface in order to make my implementation cleaner and easier to code.
The above could be worst still..consider the following additional “hack”:
public class Foobar : IFoobar
{
private readonly IFoobarAdapter _adapter;
private readonly IFoobarAdapter2 _adapter2;
private readonly IServiceLocator _serviceLocator;
public Foobar(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void DoStuffWithAdapters()
{
_adapter = _serviceLocator.GetInstance<IFoobarAdapter>();
}
public void DdoStuffWithAdapters2()
{
_adapter2 = serviceLocator.GetInstance<IFoobarAdapter2>();
}
So you *might* be thinking, well what’s wrong with that, shame on you if you are! Foobar here is quite light in that there arn’t many lines of code, but when it gets larger it will be more difficult to figure out Foobar’s dependencies from both a tools and a humans perspective.
So this then is leading to the conclusion that Service Locator is an anti-pattern right? wrong! take the following slightly different scenario.
I am using the command pattern and have a command that looks like so:
public class EmailCustomerConfirmationCommand :
ICommand<EmailCustomerConfirmationContext>
{
private IEmailAdapter _emailAdapter;
public EmailCustomerConfirmationCommand(IEmailAdapter emailAdapter)
{
//inject dependencies here.
_emailAdapter = emailAdapter;
}
public void Execute
(EmailCustomerConfirmationContext context)
{
_emailAdapter.Send(context.Customer);
}
}
So with the above I have a nice implementation of the command pattern (I’ll talk about the command pattern in a later post) that takes a context as a generic. We register this command with the context so it can be picked off the container easily. This command gets registered like so:
container.AddComponent<ICommand<EmailCustomerConfirmationContext>,
EmailCustomerConfirmationCommand>();
This of course will look different depending on your container of choice. Here I am using the Compact Container.
So my requirement is to now wireup the calling of the above command in my Foobar class. This is easy, I could just inject ICommand via the constructor like I do with all the other types, right? well I could but this will not scale very well as I might have potentially 10′s or 100′s of commands. Imagine testing that. Foobar could be a presenter layer in a MVP application or Controller layer in an MVC application or some sort of domain event. Instead, I’d like to delegate the execution of commands to another responsibility outside of class Foobar honouring the SRP (single reponsibility principle). So with that, what I want to do is something like this:
public class Foobar : IFoobar
{
private readonly IFoobarAdapter _adapter;
private readonly IFoobarAdapter2 _adapter2;
private readonly Icontroller _controller;
public Foobar(IFoobarAdapter adapter,
IFoobarAdapter2 adapter2,
IController controller)
{
_adapter = adapter;
_adapter2 = adapter2;
_controller = controller;
}
public void DoStuffWithAdapters()
{
}
public void DoStuffWithAdapters2()
{
}
public void SendNotificationEmailToCustomer(Customer customer)
{
_controller.Execute
(new EmailcustomerConfirmationContext(customer));
}
}
I have now added a dependency named IController that handles the actual execution of commands. This class could look like the following:
public class Controller : IController
{
private readonly IServiceLocator _serviceLocator;
public Controller(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Execute<TContext>(TContext context)
{
var command =
_serviceLocator.GetInstance<ICommand<TContext>>();
if (!command.IsNull())
{
command.Execute(context);
}
var disposable = command as IDisposable;
if (disposable != null)
disposable.Dispose();
}
}
So here the Controller class is nice and clean in that we are not injecting commands via the constructor or any other means. Instead we are asking Service Locator for a given command based on the context passed to it. The power of this is that the Controller class in this example also doesn’t know the underlying container it is working with.
So hopefully you can see the power the Service Locator gives us here. We have made our Foobar class very clean with little dependencies which makes it easy to test and separated out responsibilities for the actual execution of commands – much like Microsoft’s WPF framework does.
Microsoft is starting to embrace these patterns. The IDependencyResolver is Microsoft’s version of Service Locator in MVC 3. I will write a blog on that soon.
So to conclude, the Service Locator pattern is *not* an anti-pattern so long as you have a good reason to use it!
In the meantime, happy coding!