Updated: Nov 28, 2020
Based on "the Hollywood Principle"
Dependency Injection in Real World Scenario Scenario 1
You work in an organization where you and your colleagues tend to travel a lot. Generally you travel by air and every time you need to catch a flight,
Things to do :
Decide the destination, and desired arrival date and time
Call up the airline agency and convey the necessary information to obtain a flight booking.
Call up the cab agency, request for a cab to be able to catch a particular flight from say your residence
Pickup the tickets, catch the cab and be on your way.
A Little Change Affects a Lot…
If the company suddenly changes the preferred agencies and their contact mechanisms.
Substantial amount of time getting spent in the readjustment process.
Protocol changed : (Dependency Injected in real life)
An Administration Department takes complete care of your travel bookings.
The administration department did all the necessary adaptation in a manner that you do not need to do anything differently.
Changes do not affect all much :
No relearning required.
How Dependency Injection Makes a Difference ?
Impacts substantially for a larger chunk (Real Life Analogy)
That’s dependency injection in “real life”.
Imagine the cost with respect to :
A Single Person Vs. A Large Organization
The savings are likely to be substantial for the latter.
Dependency Injection in Software Context
The Conventional Approach (without DI)
In many scenarios, software components need to know :
“which” components to communicate with,
“where” to locate them, and
“how” to communicate with them.
The mechanism to “locate” the services was often left to the clients and parts of the software also needed :
To be aware of the dependencies between the various services themselves
To implicitly work out the appropriate sequencing of component initialization
To track and manage their life cycles.
For implementing DI the way to structure the code is to :
Have the clients declare their dependency on services
Have some "external" piece of code assume the responsibility of locating and/or instantiating the services
Simply supplying the relevant service references to the clients when needed.
A Few Popular DI Containers
The "external" piece of code referred to earlier is likely to be either hand coded or implemented using one of a variety of DI frameworks or ‘Containers’.
Google Guice S2Container.NET
Excalibur Castle Windsor
Dependency Injection != using a DI container
Spaghetti Code (No DI & no DI container used):
The system is highly coupled, and it’s difficult to change a single unit of code without changes rippling throughout the system.
Service Locator Anti-Pattern (DI container used without DI):
With Dependency Injection, a component “asks” for its dependencies (typically by requiring them in the constructor) rather than “looking” for them (such as by querying a Service Locator / Registry / Context).
Manual Dependency Injection (DI used without a DI container):
DI at its core is about creating loosely coupled code by separating construction logic from application logic. ‘Manual’ in the name means that dependency creation isn’t automatically handled.
Enhanced Dependency Injection (DI using a DI container):
Doing Manual Dependency Injection or Enhanced Dependency Injection, almost all of your code looks *exactly* the same, differing only at the entry point(s).
Advantage of DI
Usage of Dependency Injection :
requires just the declaration of the dependencies,
lets the framework or the container work out the complexities of service
takes care of instantiation, initialization, sequencing
supplies the service references to the clients as required.
Another look at DI
Without DI :
With DI :
Dependencies at a Very High Level
Example of a Dependency
What problems do dependencies create?
Code is tightly coupled
Difficult to isolate when testing
Difficult to test
Difficult to maintain : Questions it arises
If I change Component X how do I know what else it will affect?
Did I break anything?
Types of Dependency Injection?
Constructor (Most popular)
Injecting a ICustomerRepository and a ICustomerDTOMapper through the constructor.
* Note: This is the most popular type of injection.
Injecting a ICustomerRepository through the setter
Injecting a ICustomerRepository as well as an integer dependency through a method.
Dependency Injection Pros & Cons
Increases Testability (A LOT!)
Separates components cleanly
Allows for use of Inversion of Control Container
Increases code complexity
Some Jr. Developers find it difficult to understand at First
Can Complicate Debugging at First
Complicates following Code Flow
Design pattern – Inversion of control and Dependency injection