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!
August 24, 2011 at 8:52 pm
It may just be me, but my brain can’t compile the final example. Could it be that the signature of the final Execute method is actually like this?
public void Execute(TContext context)
That would be consistent with the usage in the FooBar class.
August 24, 2011 at 10:18 pm
Thanks for pointing out the typo.
As Execute is a templated method and the controller is not a templated class, it should be: public void Execute<TContext>(TContext context)
My post is in response to your post and many like it. Service locator is not an anti-pattern although in many cases it is. I see this a lot when developers are new to IoC and use IoC as a locator for the wrong reasons. In fact I’ve had this same discussion with the developers I’m working with right now.
The command pattern in WPF uses this same approach (service locator) to great benefit which simplifies the whole MVVM architecture.
Simon
August 25, 2011 at 7:17 pm
I’m not particularly disagreeing, although I believe that what you’ve described here isn’t a Service Locator, but rather an infrastructure component: http://blog.ploeh.dk/2011/08/25/ServiceLocatorRolesVsMechanics.aspx
What makes me say that is that I’m assuming that you don’t have tons of classes following the pattern described by Controller.Execute but rather exactly one?
August 25, 2011 at 9:04 pm
I understand what you are saying that my example isn’t a regular common use of Service Locator but the fact remains, it is using Service Locator for execution of commands. I’m using Service Locator for the power that is became a pattern. It just so happens many people have mis-used it.
I have also used it with regards to rasing domain events. So when I have a domain model, I often raise events of TEvent like so i.e:
public void Raise<TEvent>(TEvent domainEvent)
{
var handlers = locator.GetAllInstances(typeof(Handles<TEvent>));
foreach (Handles<TEvent> handler in handlers)
{
handler.Handle(domainEvent);
}
}
In the above code, locator is the Service Locator. This adds great power to a domain model changing business behaviour becomes a lot simpler and dynamic if needed. You could go all out and implement a plug-in pattern to allow for dynamically changing business requirements without a system recompile/deploy using existing frameworks like MEF.
I have also used the same kind of pattern for event aggregation. For example, intercepting the loading of types from a IoC container, then registering those types for aggregation given a certain type implements a given interface i.e. IEventHandler.Raise.
So Service Locator should be used in advanced scenarios and not as an abstract factory or to avoid DI but for more complex requirements and to implement a more abstract technical architecture.
Simon
August 25, 2011 at 9:11 pm
Sure, but all the examples you give are (or at least should be) pure infrastructure code, so that’s why I think it’s not a Service Locator per se. You may not have done it, but it’s possible to push these infrastructure components all the way out to the Composition Root.
However, at this point I believe we are arguing over the definition of what exactly is a Service Locator…
August 25, 2011 at 9:21 pm
Yes I agree, the infrastructure code and everything else i.e. handlers is always pushed out to the composition root. In my example I don’t consider handlers infrastructure code. The plug-in components is also handled in a similar manner although I don’t use this approach that often.
Simon
August 26, 2011 at 6:30 am
[...] …no lo es. Veo en smart421 lo que el autor considera un uso apropiado del patrón ServiceLocator: [...]
August 26, 2011 at 8:46 pm
@Parece:
Forgive me, what you have written looks to me like Spanish so I have translated it here to English. I don’t fully understand your comment, when you say “it is not” it is not what specifically?:
“it is not. 421 smart I see what the author considers appropriate use of pattern? N ServiceLocator”
September 19, 2011 at 2:48 pm
I thought this post warranted a more in-depth answer, so I wrote one up here: http://blog.ploeh.dk/2011/09/19/MessageDispatchingWithoutServiceLocation.aspx
January 31, 2012 at 12:15 am
[...] To IServiceLocator or not - Simon Hart Share this:Email This article was posted in Development and tagged .NET, dependency-injection, inversion-of-control, MVC, service-locator, StructureMap. Bookmark the permalink. Follow comments with the RSS feed for this post. Post a Comment or leave a trackback: Trackback URL. [...]