Inversion of Control
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.
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.
- 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.
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
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.
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.
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.
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
- 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.
Inversion of Control
- 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.