The Story Begins
It's one of those familiar terms in software engineering that you've never really bothered to learn. I mean, the name itself is rather uninviting. This seems to be a common theme in programming. There are many important but usually straightforward concepts gated behind extremely complicated sounding names such as closures, encapsulation, polymorphism, and ... dependency injection.
Imagine you have a box. This box takes certain inputs and produces certain outputs. Now in order to be useful this box presumably does some stuff inside. The question is, does this box also create something out of nothing? That is, does it only use the inputs provided or it also creates things inside that it (hopefully) uses to produce the final output?
What good software engineering suggests is that unless absolutely necessary, the box should not be producing any thing of its own but rather should get it from outside as its input.
This thing of course is something the box depends on. And I am telling you that any dependency should be injected into the box in the form of an input to the box. That's dependency injection.
But why?
By now it should be obvious that the "box" is a function. Or it's a class or any other unit in your program that's taking inputs and producing outputs. Let's go through an example.
Pretend you're building an app and one of the boxes making up this app creates a string "hello, world". It then goes on to use this string and does other stuff to finally produce some output.
Our app is getting popular and soon we have users from all over the world. But now we want to offer the app in multiple languages. Now each box where we created a string like our "hello, world" needs to be modified to first pass that string through a translate()
function. But that's messing up our unit tests based on the system language and now we have to update all of those as well.
The principle of dependency injection is asking us:
If a box is creating something inside it, does it absolutely have to be created within the box?
In our case, the thing that our box is creating internally is the "hello, world" string and no, it most certainly does not have to be created inside the box.
Here we should realize that the string is a dependency of the box and should be lifted outside. So we simply pass the string as an input. Now our unit tests for this box still work deterministically and we can pass translated strings as inputs if necessary.
Conclusion
Next time you're writing code and working on a function, just question yourself -- is it necessary for everything originating from inside the function to be created there? If not, inject it from the outside instead.
Top comments (0)