Inversion of Control & Dependency Injection Go Hand in Hand
What is Inversion of Control (IOC)?
Sometimes referred to as Dependency Inversion Principle (DIP)
Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework. It's most often used in the context of object-oriented programming.
The principle states that high level or low level modules should not depend upon each other, instead they should depend upon abstractions.
Specific implementations (object instances) are deferred to a higher level of abstraction of control.
Referred to as the “Hollywood Principle”
“Don’t call us, we will call you.”
Inversion of Control can be achieved through various mechanisms such as: Strategy design pattern,
Service Locator pattern
Dependency Injection (DI).
A depiction of 'with' and 'without' IOC scenarios
DI (Dependency Injection) is one of the ways to implement ‘IOC’ Design Pattern
IOC is a technique which helps in object creation at run time instead of compile time.
Whenever or wherever a particular object or a collection of objects are required, this sort of binding is achieved with the help of dependency injection.
“Do not instantiate me I will be instantiated myself (by external factor)” IOC deals with problem of Tight Coupling.
Let’s bring in the zoo example to explore this concept further
The above example leads to 3 main issues.
Life cycle dependency:
AnimalService class is responsible for instantiation of Elephant object, so the service class is responsible for life cycle of the Elephant class.
Any change in Animal (Elephant) class might lead to recompilation of service class.
Concrete class dependency:
If we add a new Animal class (Lion) this will also require changes in our service class.
Hence, lead to recompilation of service class.
Getting out of problem:
How can we handle this problem?
Surely the solution is IOC in our case :
First remove the process of object instantiation from service class,
Secondly instead of using concrete class use abstraction and inject the required concrete class as per requirement.
IOC Design solves the problem
Here is an example of IOC within Spring frame work will help us to achieve this result by shifting the object creation task/role/control from the Service class to Spring.
Let's analyze this further with our zoo example
Components in the zoo example :
A ‘Manual Dependency Injection’ (XML-Driven) Scenario
DI implementation through XML
Annotation-Driven example implicitly works same as the xml example above
DI implementation using XML OR Java ?
Some Contentious Topics
There are a few areas where there has been a fair degree of debate (often between the authors/supporters of the specific DI frameworks). One of these is:
XML OR Java
Some prefer the wiring up of the dependencies and their relationships to be done using Java code – many others prefer using XML.
At times it appears to be simpler to work with Java code.
However, there is at least one scenario where XML is the only reasonable choice:
This is when you ship binaries, but would like to allow for administrators / system integrators / end users to be able to modify / enhance the default functionality by plugging in different implementations for the services (deployment specific variations). Your end users are far more likely to be able to modify your XMLs (assuming you documented them well) rather than your source code (assuming you shipped it).