Inversion of Control | Dependency Injection

Service Locator

Problem

You have classes that have dependencies on services or components whose concrete type is specified at design time. In this example, ClassA has dependencies on ServiceA and ServiceB.
Dependencies.png
Figure 1
ClassA has dependencies on ServiceA and ServiceB

This situation has the following problems:
  • To replace or update the dependencies, you need to change your class source code.
  • 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 the services (therefore, you cannot replace the service implementations with mock implementations).
  • Your classes contain repetitive code for creating, locating, and managing their dependencies.

Forces

  • You want to decouple your classes from their services so the services can be replaced or updated with minimal changes, or no changes, to your classes' source code.
  • You want to write classes that depend on services whose concrete implementation is not known at compile time.
  • You want to test your classes in isolation, without using the dependencies.
  • You want to decouple your classes from being responsible for locating and managing the lifetime of dependencies.

Solution

Create a service locator that contains references to services and encapsulates the logic to locate them. In your classes, use the service locator to obtain service instances, as illustrated in Figure 2.
ServiceLocatorUseCase.PNG
Figure 2
The ClassA uses the service locator to get an instance of the ServiceA

The service locator holds references to services. It is not responsible for instantiating those services. The service locator provides a way to register services. After the service is registered, the service locator can find it.

Note:
The service locator should provide a way to locate a service without specifying the concrete type. For example, it could use a string key or a service interface type.

Implementation Notes

The Service Locator pattern can be implemented in several ways. For example, the service locator could be a singleton global instance that holds references to services.
In the Composite Web Application Block, composition containers contain a Services collection to hold references to services. Modules use this collection to register and locate services. For more information about how services are located in the Composite Web Application Block, see the section “Locating Services” in the Services topic.

Liabilities

  • There are more solution elements to manage.
  • You have to write additional code to add service references to the locator before your objects can use it.
  • Your classes have an extra dependency on the service locator.
  • The source code has added complexity, which makes it more difficult to understand.

Related Patterns

  • Dependency Injection. The Dependency Injection pattern solves the same problems that the Service Locator pattern solves, but it uses a different approach.
  • Inversion of Control. The Service Locator pattern is a specialized version of the Inversion of Control pattern.
Inversion of Control | Dependency Injection

Last edited Jan 17, 2008 at 4:13 PM by siacomuzzi, version 3

Comments

No comments yet.