Dependency Injection or Inversion?
The hardest thing about being a software developer, for me, is coming up with names for things. I’ve worked out a system with which I’m sort of comfortable where, when coding, I pay attention to every namespace, type, method and variable name that I create, but in a time-box (subject to later revisiting, of course). So I think about naming things a lot and I’m usually in a state of thinking, “that’s a decent name, but I feel like it could be clearer.”
And so we arrive at the titular question. Why is it sometimes called “dependency injection” and at other times, “dependency inversion.” This is a question I’ve heard asked a lot and answered sometimes too, often with responses that make me wince. The answer to the question is that I’m playing a trick on you and repeating a question that’s flawed.
Dependency Injection and Dependency Inversion are two distinct concepts. The reason that I led into the post with the story about naming is that these two names seem fine in a vacuum but, used together, they seem to create a ‘collision,’ if you will. If I were wiping the slate clean, I’d probably give “dependency inversion” a slightly different name, though I hesitate to say it since a far more accomplished mind than my own gave it the name in the first place.
My aim here isn’t to publish the Nth post exhaustively explaining the difference between these two concepts, but rather to supply you with (hopefully) a memorable mnemonic. So, here goes. Dependency Injection == “Gimme it” and Dependency Inversion == “Someone take care of this for me, somehow.” I’ll explain a bit further.
Dependency Injection is a generally localized pattern of writing code (though it may be used extensively in a code base). In any given method or class (or module, if you want) rather than you going out and finding or making the things you need, you simply order your collaborators to “gimme it.”
So instead of this:
public Time getTheTime() {
ThingThatTellsTime atom = new CesiumAtom();
return atom.getMeTheTimeSomehow();
}
You say, “nah, gimme it,” and do this instead:
public Time getTheTime(ThingThatTellsTime whatever) {
return whatever.getMeTheTimeSomehow();
}
It isn’t you responsible for figuring out that time comes from atomic clocks which, in turn, come from atoms somehow. Not your problem. You say to your collaborators, “you want the time, Buddy? I’m gonna need a ThingThatTellsTime, and then it’s all yours.” (Usually you wouldn’t write this rather pointless method, but I wanted to keep the example as simple as humanly possible).
Dependency Inversion is a different kind of tradeoff. To visualize it, don’t think of code just yet. Think of a boss yelling at a developer. Before the ‘inversion’ this would have been straightforward. “Developer! You, Bill! Write me a program that tells time!” and Bill scurries off to do it.
But that’s so pre-Agile. Let’s do some dependency inversion and look at how it changes. Now, boss says, “Help, someone, I need a program that tells time! I’m going to put a story in the product backlog” and, at some point later, the team says, “oh, there’s something in the backlog. Don’t know how it got there, exactly, but it’s top priority, so we’ll figure out the details and get it done.” The boss and the team don’t really need to know about each other directly, per se. They both depend on the abstraction of the software development process; boss has no idea which person writes the code or how, and the team doesn’t necessarily know or care who plopped the story in the backlog. And, furthermore, the backlog abstraction doesn’t depend on knowing who the boss is or the developers are or exactly what they’re doing, but those details do depend on the backlog.
Okay, so first of all, why did I do one example in code and the other in anecdote, when I could have also done a code example? I did it this way to drive home the subtle scope difference in the concepts. Dependency injection is a discrete, code-level tactic. Dependency inversion is more of an architectural strategy and way of structuring (decoupling) code bases.
And finally, what’s my (mild) beef with the naming? Well, dependency inversion seems a little misleading. Returning to the boss ordering Bill around, one would think a strict inversion of the relationship would be the stuff of inane sitcom fodder where, “aha! The boss has become the bossed! Bill is now in charge!” Boss and Bill’s relationship is inverted, right? Well, no, not so much — boss and Bill just have an interface slapped in between them and don’t deal with one another directly anymore. That’s more of an abstraction or some kind of go-between than an inversion.
There was certainly a reason for that name, though, in terms of historical context. What was being inverted wasn’t the relationship between the dependencies themselves, but the thinking (of the time) about object oriented programming. At the time, OOP was very much biased toward having objects construct their dependencies and those dependencies construct their dependencies, and so forth. These days, however, the name lives on even as that style of OOP is more or less dead this side of some aging and brutal legacy code bases.
Unfortunately, I don’t have a better name to propose for either one of these things — only my colloquial mnemonics that are pretty silly. So, if you’re ever at a user group or conference or something and you hear someone talking about the “gimme it” pattern or the “someone take care of this for me, somehow” approach to architecture, come over and introduce yourself to me, because there will be little doubt as to who is talking.
Thanks — this is perfect for a presentation I’m giving next week. 🙂
Glad to hear it helped. Good luck with the presentation 🙂
Is ‘dependency inversion’ the same term as ‘inversion of control’ ?
Not quite. Let’s use Erik’s Dependency Injection example. Dependency Inversion comes into play in the choice to depend on ThingThatTellsTime rather than CesiumAtom directly. The former is an abstraction, implemented by CesiumAtom and depended upon throughout the app. So we have an abstraction, and we have modules that depend on the abstraction, but something’s missing: an actual implementation of ThingThatTellsTime to make our app work. IoC is a pattern, typically supported by a generic “container” framework, to solve the general problem of fulfilling modules’ dependencies. In this particular example we would configure our IoC container to provide a CesiumAtom whenever… Read more »
Nice explanation. Was thinking about adding an addendum to the post, but now I don’t have to.
I disagree, IOC and DIP are interchangeable. IOC and IOC CONTAINER are 2 vastly different items. As long as you aren’t referring to a container as “IOC” all is well.
IOC is a principle, an IOC container is a detail on how to implement the principle. IOC is NOT A PATTERN http://en.wikipedia.org/wiki/Inversion_of_control ” inversion of control (IoC) describes a design” it is a design or principle, not a pattern.
The IOC container is not a pattern either, an IOC container is a library that leverages the service locator and factory patterns to instantiate objects.
Yes.
I wish that style of programming was dead! I still see objects constructing their dependencies all the time in new code, or even worse service locating a singleton. Granted, I imagine the audience for your blog probably stop doing silly things like this long ago. Another great post!
Thanks — glad you liked! And yeah, thinking on it I’m fortunate because over the last several years I’ve generally been working either in green field code bases or else I’m specifically being brought in to help factor legacy code bases away from this sort of thing. It’s been quite some time since I’ve had to live with this style of programming and I don’t miss it at all.
Singletons aren’t inherently bad if they’re used well. They’re even easily testable if you allow back doors into their state.
The other thing is you can use poor man’s dependency injection https://software2cents.wordpress.com/2013/03/29/poor-mans-dependency-injection/ to achieve many of the benefits of DIP/IOC without the need of a container. This is a really frictionless change that you could instill in your own code and evangelize in your organization.
This will leave the simplicity of new MyService() that other team members are used to.
I agree with the IOC / DIP being interchangeable. There’s a memorable post on c2.com regarding this subject http://c2.com/cgi/wiki?HollywoodPrinciple which I strongly recommend. As an off-topic, I believe singletons were never intended to be used by regular app programmers (end-programmers, if you will), but to become part of infraestructure – plumbing code. I mean, how do you even know you will only need ‘one’ of a kind. What if you end up needing more than one instance? Why introduce extra stress on your app by putting such a hard constraint? Plus, you’re mixing two concerns in the same code unit,… Read more »
Your take on singletons seems very much in line with mine as well. I see people say that there can be good uses of them and, while I suppose that’s theoretically true, I’ve never actually witnessed any in the wild. They always just wind up being dumping grounds for global variables and ways to have two unrelated classes talk to each other.
I’ve always found them to be awkward at best (there is something deeply but subtly weird about controlling your own cardinality) and most commonly complete architectural nightmares.
For what it is worth, here is when the idea of dependency inversion clicked for me. Thinking of a simple data layer above a database, it exposes CreateX(), UpdateX(), ReadX(), DeleteX() methods. It exposes them because that is what the underlying data store exposes. Rather than having the consumer depend upon the interface exposed by the data layer, the consumer exposes the interface which it expects data layers to implement. It may be something nicer like ReturnAllCustomersWhoPayBillsOnTime(). All data layers then take their dependency on that interface, and implement it. Inverting that dependency allows for several implementations of the data… Read more »
That makes sense, and it’s more true to the inversion name (though the thing being inverted seems to be allowing consumers rather than producers to define APIs). This reminds me of the “magic oracle” concept I posted about once, where when writing a method and thinking of what to abstract out you think, “if I could have a magic box, what would I ask it to do for me?”
Yeah, I definitely want to second Eric’s comment. In dependency inversion, consumers are the ones that define the API. I’d say if you have some “Consumer” using some “Library”, there’s two broad versions of this. First, maybe Library has some class, or set of classes, which you want to abstract. Like maybe it has a bunch of ProbabilityDistribution classes, for different types of distribution. To invert that dependency, you’d want to write your own IProbabilityDistribution (or similar) interface, then use adapters to adapt from the Library classes to your interface. If you’re following DIP then IProbabilityDistribution will be defined by… Read more »
Eric, this might blow your mind but your example of ReturnAllCustomersWhoPayBillsOnTime() there is no reason for an interface. This can be a concrete class with virtual ReturnAllCustomersWhoPayBillsOnTime(). This is actually more honest. You are not going to have multiple providers of ReturnAllCustomersWhoPayBillsOnTime(), you have 1 single tightly coupled contract to your persistence of choice. The fact that you have a repository injected into your class that exposes ReturnAllCustomersWhoPayBillsOnTime() is an implementation detail and SHOULD be hidden from the public contract. If you have a detailed and specific interface that is implemented by exactly one class, that is a bad abstraction.… Read more »
The simplest way to draw clarity between dependency injection and inversion is to only refer to dependency inversion as the dependency inversion principle (DIP).
It becomes extraordinarily clear when you use the full name. Principles are very different from actions to follow them, such as using DI to satisfy DIP. The second way to eliminate all confusion is instead of referring to DIP you can interchangeably use IOC.
That’s a good call. Thinking of the “Principle” in DIP really drives home the distinction I was drawing between strategy (DIP) and tactics (Dependency Injection). “Principles” communicate “theoretical/strategic.”
Would “dependency abstraction” be a more accurate term for “dependency inversion”?
Can’t really speak to better, per se, but that seems clearer… to me, anyway.