Hot dog! It's a joke!
A Zen master approaches a hot dog stand and says:
"Make me one with everything!"
Alan Watts. Sometimes a Zen master. Perhaps at times a hot dog stand vendor.
I thought about this while listening to a colleague's lecture on Dependency Injection. He asked the question:
Why do we use Dependency Injection?
Good question! I spent most of the time reading up on Dependency Injection trying to understand what it is, not why one would do that! So I thought of a way to clarify both what it is, and why one does it. I've used it so much without really knowing why, or truth be told, how. Hit that Ballmer Peak, boy!
What is Dependency Injection?
This is perhaps best understood by asking how one does Dependency Injection. Dependency Injection is achieved in three ways:
- Constructor Injection involves providing dependencies through the constructor
- Setter Injection occurs when dependencies are set via public methods
- Interface Injection is similar to setter injection, but instead of injecting concrete classes, interfaces are injected
We can see from how Dependency Injection is done exactly what it is:
Dependency Injection is a technique that allows a class to receive its dependencies from outside.
Why would you use dependency injection?
Getting back to the Zen master, he just asks the hot dog stand vendor to make him a hot dog. An extremely lush hot dog. With everything. In an abstract sense.
The opposite of being abstract is being concrete. That would be when the Zen master says make me this specific hot dog, with these particular ingredients I've provided, in this particular way. Not very Zen, dude. This means both the Zen master and the hot dog stand vendor are responsible for some of the same dependencies. There isn't a clear separation of concerns between hot dog vendor and Zen master.
With Dependency Injection, the Zen master relies on the abstraction of a lush hot dog with everything. The hot dog builder builds the hot dog by injecting all the dependencies, and then provides the prefab hot dog already instantiated and ready to clog some Zen arteries.
A hot dog vendor. Not necessarily a Zen master.
What problem(s) occur when the hot dog vendor depends on the Zen master to provide all the dependencies? That is tight coupling. That is when someone as abstract as a Zen master relies on low-level details like whether there should be chili and onion or just tomato sauce and mustard.
Perhaps now we can see why by asking:
What do we achieve with Dependency Injection?
- There is a separation of concerns between object creation, and object use
- High-level modules like Zen masters do not depend on low-level modules like chilis and onions. Neither does the hot dog vendor: A hot dog without chili is still a hot dog. In this way, it is safe to say that both Zen masters and hot dog vendors rely on abstractions instead of on implementations
- The abstraction of a hot dog with everything does not rely on the details of chilis and onions. Those details depend on abstractions. On some days, there is chili. On some days there is not. It's still a hot dog. With everything in the shop. One with everything. Very Zen
Conclusion
Dependency Injection is a technique employed to inject dependencies into a class from outside. Why would you want to do that? In order to separate the creation and the use of the object. In this way, high-level modules do not depend on low-level modules, and low-level modules do not depend on high-level modules. Both depend on abstractions. In turn, abstractions do not depend on details. Details depend on abstractions.