Inversion of Control

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

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. Figure 1 illustrates this pattern.

Ff709849.7d040a77-02b3-4217-804c-58112cea747a(en-us,PandP.10).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 the source code of your classes.
  • The concrete implementations of the dependencies have to be available at compile time.
  • Your classes are difficult to test in isolation because they have direct references to dependencies. This means that these dependencies cannot be replaced with stubs or mocks.
  • Your classes contain repetitive code for creating, locating, and managing their dependencies.

Forces

  • You want to decouple your classes from their dependencies so that the dependencies can be replaced or updated with minimal or no changes to the source code of your classes.
  • You want to write classes that depend on classes whose concrete implementations are 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

Delegate the function of selecting a concrete implementation type for the class dependencies to an external component or source.

Implementation Details

The Inversion of Control pattern can be implemented in several ways. The Dependency Injection pattern and the Service Locator pattern are specialized versions of this pattern that delineate different implementations. Figure 2 illustrates the conceptual view of both patterns.

Ff709849.5ef15f40-11c0-4e71-9ea1-a467c0e8e892(en-us,PandP.10).png

Figure 2

Conceptual view of the Service Locator and Dependency Injection patterns

For more information about these patterns, see Dependency Injection and Service Locator.

Liabilities

  • You need to implement a mechanism that provides the dependencies that are required by the object that is being initialized.
  • There is added complexity to the source code, which makes it harder to understand.

Related Patterns

  • Service Locator. The Service Locator pattern is a specialization of the Inversion of Control pattern. The Service Locator pattern introduces a locator object that other objects use to resolve dependencies.
  • Dependency Injection. The Dependency Injection pattern is a specialization of the Inversion of Control pattern. The Dependency Injection pattern uses a builder object to initialize objects and provide the required dependencies to the object.