The Service Locator Pattern
You have classes with dependencies on services whose concrete types are specified at compile time. In the following example, ClassA has compile time dependencies on ServiceA and ServiceB. The following diagram illustrates this.
Classes with dependencies on services
This situation has the following drawbacks:
- To replace or update the dependencies, you must change your classes' source code and recompile the solution.
- The concrete implementation of the dependencies must be available at compile time.
- Your classes are difficult to test in isolation because they have a direct reference to their dependencies. This means that these dependencies cannot be replaced with stubs or mock objects.
- Your classes contain repetitive code for creating, locating, and managing their dependencies.
The next section describes how to address these issues.
Use the Service Locator pattern to achieve any of the following objectives:
- You want to decouple your classes from their dependencies so that these dependencies can be replaced or updated with little or no change to the classes.
- You want to write logic that depends on classes whose concrete implementation is not known at compile time.
- You want to be able to test your classes in isolation, without the dependencies.
- You do not want the logic that locates and manages the dependencies to be in your classes.
- You want to divide your application into loosely coupled modules that can be independently developed, tested, versioned, and deployed.
Create a service locator that contains references to the services and that encapsulates the logic that locates them. In your classes, use the service locator to obtain service instances. The following diagram illustrates how classes use a service locator.
How classes use a service locator
The Service Locator pattern does not describe how to instantiate the services. It describes a way to register services and locate them. Typically, the Service Locator pattern is combined with the Factory pattern and/or the Dependency Injection pattern. This combination allows a service locator to create instances of services.
A service locator should be able to locate a service without knowing its concrete type. For example, it might use a string key or a service interface type. This allows you to replace the concrete implementation of the dependency without modifying the classes.
The SharePoint Guidance Library offers an implementation of the Service Locator pattern. The SharePointServiceLocator class provides access to a singleton IServiceLocator instance and manages that instance. The SharePointServiceLocator class includes a default implementation of the interface. This is the ActivatingServiceLocator class. This class can both create and locate services.
The Partner Portal application shows how to use the Service Locator to register and locate services such as repositories, logging services, and configuration management services. For more information, see The SharePoint Service Locator.
Consider the following points before you use the Service Locator pattern:
- There are more solution elements to manage.
- You must write additional code that adds service references to the service locator before your objects can use it.
- Your classes have a dependency on the service locator.
- The source code is more complex and difficult to understand.
- You can use configuration data to define run-time relationships.
- You must provide implementations of the services. Because the Service Locator pattern decouples service consumers from service providers, it might be necessary to provide additional logic. This logic ensures that the service providers are installed and registered before service consumers try to locate them.
The following patterns are related to the Service Locator pattern:
- Dependency Injection. This pattern solves the same problems as the Service Locator pattern, but it uses a different approach.
- Inversion of Control. The Service Locator pattern is a specialized version of this pattern. It inverts an application's traditional flow of control. It is the object that is called instead of the caller that controls a process.
For more information about the Service Locator pattern, see the following articles:
- Inversion of Control and the Dependency Injection pattern on Martin Fowler's Web site
- Service Locator on MSDN
For more information about the Service Locator, see The SharePoint Service Locator.