I’ve been putting off a follow-up on Dependency Injection for a couple of months now. The amount of heat I anticipate receiving is so disproportional to the probable light gained that it makes me hesitate. This weekend, I picked up on a stream of referrals from a post at InfoQ that mentions my Dependency Injection post (though not the follow-ups). It does a reasonable job of spelling out the conversation that happened, though I was feeling picked on until it brought in Eli Lopian’s contribution to the discussion. In whole, it’s a good summary. The real pile-on happens in the comments and it illustrates so much of what I dislike in software development sloganeering that it has jolted me out of my reluctance to respond (I’d have responded there, but you have to register to comment and I hate that).
There are two things that contribute to the silver-bullet, band-wagon boosterism that sends up red flags for me.
Good for What Ails You
This is characterized best by a comment by Steven Devijver when he says
It’s an interesting discussion. Just as interesting as asking oneself: shall I wear underwear or shall I try something really nifty today?
It’s the same kind of thing pointed out by Jay Kimble about a month ago as he expressed his concern with Dependency Injection.
I have been asked "Why don’t you like this pattern or that pattern? I mean [Some famous blogger] says s/he always uses them. I think they are smart or at least they seem to be. You must be a 'Mort' or a pretender..." At least that’s the way it has always been stated to me.
The claim made by these individuals is that The Pattern (it can be any pattern, but this is increasingly frequent when referring to Dependency Injection) is universally applicable and should be used in all cases, preferably by default. I’m sorry, but this line of argument only shows the inexperience or narrow focus of those making the claim.
Claims of universal applicability for any pattern or development principle are always wrong.
Study any pattern or development principle in enough depth and you’ll find the edge cases and counter-indicators applicable to it. This is true of even basic principles like data normalization and object oriented design.
Variations on the universal applicability include the pseudo cost-benefit comments like that from Gabriel Lozano-Moran.
If you anticipate [no] potential future problems using a DI framework like Spring.NET and it takes you a couple of minutes to implement this hardly violates the YAGNI principle.
I call this "pseudo cost-benefit" because it seriously under-values initial implementation, training, and the burden of long-term skill set dependency created by implementing so invasive a pattern—a point I made at the end of my post about small company line-of-business software development a bit back. Yeah, you can probably add Spring.Net to a given project in just a couple of minutes, but that treats Spring.Net familiarity as a sunk cost (or worse, null cost) and commits that project indelibly to Spring.Net familiarity. You may feel that familiarity with Spring.Net is a given for any competent developer, but that proves my point that this is merely a variation of treating DI as a given for all projects in all situations.
Save Me From Myself
This argument is made in a comment by Ole Friis.
When I use DI, I see it as an advantage that I am forced into splitting up my application in well-defined services with a nice interface.
The term "forced" here indicates that he doesn’t trust himself to split his applications into "well-defined services with a nice interface" on his own. In this, Ole Friis is echoing the response I got from the intimidating Oren Eini when I suggested that TypeMock makes arguments that couple DI with unit testing go away.
The main weakness of Type Mock is its power, it allow me to take shortcuts that I don’t want to take, I want to get a system with low coupling and high cohesion.
The implication is that he wouldn’t be developer enough to create a system with low coupling and high cohesion if he used powerful tools like TypeMock. Oren is inconsistent here because he’s otherwise all for developer empowerment as illustrated by his support for Jeffrey Palermo’s excellent post regarding treating developers as professionals.
The fact is that nobody is really in favor of limiting themselves. Taken seriously, these kinds of statements indicate a profound lack of trust in their own competence. I’ve never yet met a software developer above Jr. level with that particular insecurity. I’ve met a veritable host who lack trust in the competence of people they work with, however, which is what I suspect is really behind these statements. Either way, it’s hard to take that argument seriously.
I’m the Anti-DI
Or so I’ve been painted. The fact is that I’m not, though my use for it is pretty limited. Since I don’t need it as a foundation for mocking objects in unit testing, it’s only really useful when I have a service with more than one implementation and I’ve found that even then DI isn’t necessarily the answer. I’ll deal with at least two reasons behind this in a future post(s).