Injection and Inversion
Posted by indroneel on April 4, 2007
A lot of programmers I interact with are unable to differentiate between dependency injection and inversion of control. Thanks to the popularity of Spring framework and EJB 3.0 there is now a tendency to use these terms interchangeably, even as they represent distinctly different concepts, resulting in a lot of ambiguities.
Inversion of control has its antecedents in the Hollywood principle (don’t call us, we’ll call you) and is not a design pattern. Rather, it is a general principle that is realized in multiple design patterns. Dependency injection is one such pattern that builds on top of this principle. Inversion of control is one of the tenets for all object-oriented frameworks, but not all object-oriented frameworks provide the features of dependency injection.
An object-oriented framework is a semi-finished application encapsulating common features that are repeated across different parts of the same application and even across applications. Common examples of such framework include J2EE containers, Apache Struts, Eclipse rich client platform and Swing GUI toolkit.
A framework-driven approach to application development usually involves integration of multiple object-oriented frameworks and creation of specific functionalities as extensions to these frameworks. Every framework provide its own extension mechanisms as pre-defined endpoints called hotspots. Hotspots are specific to a framework, usually pertaining to integration (application programming/service provider interfaces) and configuration (external metadata).
For example, the EJB 2.0 specifications define hotspots for Java bean objects to be deployed in an EJB container. This definition takes the form of base interfaces, method signature conventions and context-based references to other objects and resources.
Inversion of Control
Inversion of control is manifested at integration hotspots during communication between the static framework structure and custom application logic (implemented as extensions and plugins). A common characteristic of object-oriented frameworks is to maintain overall control of all activities within the hosted application. The primary objective of application modules is thereby restricted to provide functionalities that can be invoked by the framework. Compare this to a scenario without frameworks, in which there is a significant effort on how the modules can invoke and manage each other, effectively transferring control during the process. This change in focus, and the low-level design changes it entails, is what inversion of control is all about.
When deployed on top of an object-oriented framework, application modules should not directly access each other’s capabilities. The same is also true for invocations from external entities. Instead, every request must be routed through the hosting framework. The latter, in turn, can make multiple calls across more than one module in a controlled fashion before returning a result back to the caller.
In the light of what has been said so far, inversion of control can be summed up as:
“Always expect to be called. If you ever need to call, never call direct. Always ask the framework. The framework knows.”
Modules and components that constitute an application never exist in isolation. They need to refer to each other to execute their respective functionalities.
In a framework-driven scenario, modules access each other’s capabilities indirectly through the framework. Typically, this involves querying the framework to first obtain a reference to the target module (this process is better known as the service locator pattern). Subsequent method invocations are then made with respect to this reference.
There are several problems with the service locator approach. They are as listed below:
- Each module that originates a call must be hand-coded with the query information (unique identifiers) for the target modules.
- The module implementation needs to include the extra logic involved to perform lookups for target modules.
- The query information and operations are specific to the framework. This makes the modules less portable across frameworks.
This is where dependency injection comes in handy.
In many respects, dependency injection is an antithesis to the service locator pattern. Under dependency injection, modules no longer lookup each other to invoke specific functionalities. Instead, each module ‘indicates’ its preferences for a choice of capabilities in collaborating modules. The indication mechanism usually varies depending on the capabilities of the underlying programming language.
For example, dependency injection under Java usually relies on method signature convention and annotations using a language capability called introspection. Constructors with multiple parameters and bean-style setter methods are taken to be injection points by convention. Ad-hoc methods with one or more parameters can be annotated to be recognized as injection points.
The wiring among different modules is performed by an external entity called the dependency injector. In a framework-based environment, the framework itself plays the role of injector, instantiating invoking the glue-code on modules as necessary.
What Causes the Confusion?
It is a common practice to provide the features of dependency injection as part of much larger object-oriented frameworks. While extolling the advantages of such frameworks, it is natural to stress on the inversion of control principles (the fact that this is a common characteristic across all frameworks is seldom mentioned). Somewhere down the line, the distinction between the two gets blurred with end users. This is further compounded by the fact that dependency injection builds on top of inversion of control making it impossible to separate the two.
Of special mention in this regards is the Spring framework that is repeated touted as an inversion of control container on multiple forums. While this is factually correct, a more apt description should highlight its dependency injection features to avoid confusion.
 Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
 Stefano’s Linotype: Origin of the Hollywood Principle sheds some light on the origin of Inversion of Control.
 Object-Oriented Application Frameworks by Mohamed Fayad and Douglas C. Schmidt.