Inversion of control / Dependency injection — what is it?
Assume you depend on two or objects to create a functional representation of “Add to cart” implementation. This can be achieved traditionally via:
- create objects of all dependencies and use such objects for your implementation
- use Dependency injection like “Spring” , “PicoContainer”
As per Spring in Action, 2nd. Ed. by Craig Walls – Dependency injection is described as:
“Any nontrivial application is made up of two or more classes that collaborate with each other to perform some business logic. Traditionally, each object is responsible for obtaining its own references to the objects it collaborates with (its dependencies). When applying DI, the objects are given their dependencies at creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects.”
Dependency Injection was originally called Inversion of Control (IoC) because the normal control sequence would be the object finds the objects it depends on by itself and then calls them. Here, this is reversed: The dependencies are handed to the object when it’s created. This also illustrates the Hollywood Principle at work: Don’t call around for your dependencies, we’ll give them to you when we need you.
It delivers a key advantage: loose coupling. Objects can be added and tested independently of other objects, because they don’t depend on anything other than what you pass them.
(When using traditional dependencies, to test an object you have to create an environment where all of its dependencies exist and are reachable before you can test it. With Dependency Injection, it’s possible to test the object in isolation passing it mock objects for the ones you don’t want or need to create. )
Adding a class to a project is facilitated because the class is self-contained, so this avoids the “big hairball” that large projects often evolve into.
The challenge of DI is writing an entire application using it. A few classes are no big deal, but a whole app is much more difficult. For entire applications, you frequently want a framework to manage the dependencies and the interactions between objects. DI frameworks are often driven by XML files that help specify what to pass to whom and when. Spring is a full-service Java DI framework; other lighter DI frameworks include NanoContainer and the even more lightweight PicoContainer .