A pattern that is showing up frequently in .Net development at the moment is Service Locator. It has appeared in the Composite Application Library (Prism - intended for use in Silverlight and WPF applications) as well as ASP.Net MVC. Service Locator is often seen going hand in hand with DI and IoC and one useful implementation of Service Locator might be to decouple an application from specific IoC containers (i.e. use the Service Locator pattern on top of IoC).
In essence, Service Locator is a simple pattern:
“Provide a global point of access to a service without coupling users to the concrete classMartin Fowler describes the pattern in the following terms:
that implements it.” *
“The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need.” **
The Composite Application Library documentation offers a number of drawbacks to Service Locator:
“The Service Locator pattern has the following liabilities:
- There are more solution elements to manage.
- You have to write additional code to add service references to the locator before your objects use it.
- Your classes have an extra dependency on the service locator.
- The source code has added complexity; this makes the source code more difficult to understand.” ***
In short the criticism is that Service Locator adds complexity to the application. Martin Fowler also notes that use of Service Locator can lead to testability issues:
“I've often heard the complaint that these kinds of service locators are a bad thing because they aren't testable because you can't substitute implementations for them. Certainly you can design them badly to get into this kind of trouble, but you don't have to.”
Common Service Locator
Many frameworks (including MVC 3) are now working to the Common Service Locator library. This is described in the following terms:“The Common Service Locator library contains a shared interface for service location which application and framework developers can reference. The library provides an abstraction over IoC containers and service locators. Using the library allows an application to indirectly access the capabilities without relying on hard references.”A number of IoC frameworks already provide implementations of the core interface (IServiceLocator) including Spring.Net, Unity, and Castle Windsor. The IServiceLocator interface requires that an IoC container provide the following methods:
TService GetInstance<TService>(); object GetInstance(Type serviceType, string key); TService GetInstance<TService>(string key); IEnumerable<object> GetAllInstances(Type serviceType); IEnumerable<TService> GetAllInstances<TService>();
This is interesting but one has to ask if it’s an abstraction too far.
Update: If you are considering using the Service Locator pattern you should be aware that it is regarded by many as an anti-pattern. See Service locator anti-pattern.
* Service Locator, Game Programming Patterns / Communicating Patterns
** Using a Service Locator, Martin Fowler
*** Service Locator