Dependency Injection Objection

by Jacob 9. December 2007 00:46

CourtFight 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.

Consenting AdultsThe 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).

Tags: , , , ,

Programming

Comments


December 10. 2007 22:17
David Fauber
"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"

Mmm this is almost a strawman in my opinion.  Just because one prefers to use a tool to enforce a design/pattern/standard/whatever doesn't necessarily imply that they couldn't achieve similar results without that tool.  Its just that automating removes the human imperfection, and leaves you one less thing to worry about.

That said, I don't have really strong feelings on DI (how weird am I?), but have agreed with most of your reasoning throughout this and think you have stood up quite well to the bandwagon dogpiling, hang in there! Laughing



December 11. 2007 03:48
Gabriel Lozano-Moran
Imho this is another theological discussion in the same context as my editor is better than your editor. I can give you another example, if you use the Web Service Software Factory and by pushing on a button it will generate for you several projects and with a 2nd right-click the MVC pattern for you or even implement DI this is not a violation of the YAGNI principle. If you waste precious time however on DI when you don't need it than this is a violation of YAGNI, code generation is not. In the time that people are having the discussion on whether or not to use DI you would have implemented DI in your current project Wink


 Jason 
December 11. 2007 13:15
Jason
I have been waiting for a follow-up to see if your opinion changed after some time. I agree with your stance on the matter. I don't have any enlightening words of wisdom to add here, just wanted you to know that there is at least one other developer who understands and agrees with your opinion.


December 11. 2007 13:40
Jacob
@Gabriel while I agree with you about the utility of code generation (I'm a huge fan of code generating frameworks), my point still stands about both the sunk cost and familiarity needed to use the framework. DI frameworks are extremely useful (I can't imagine using DI without a framework particularly when so many quality frameworks exist no matter your coding environment), but it's good to remember that they still have both an initial cost (installing on developer machines, keeping current on updates, educating on proper usage and standards) and an ongoing cost (in the form of a skill set dependence) to the project that uses it. That's really my point here.  I'm not saying that DI is bad or wrong, I'm just insisting that it has a non-zero cost that needs to be taken into account when using it.


December 12. 2007 04:41
Gabriel Lozano-Moran
I agree. I have had the similar discussion with my co-coach. For a current project we have to use SQL Server but the customer already mentioned that in the future they want to support Oracle as well. We are talking about a commercial product that will be deployed on-site therefore we need to use Spring.NET in advance. A violation of the YAGNI principle would be imho to use Spring.NET between all layers because it might be possible that in future versions the customer wants to replace the BusinessLogic layer with a new implementation. But then again if this is a customer requirement...


December 12. 2007 05:41
Andrew Myhre
@Gabriel: Surely YAGNI is about what is implemented as opposed to what effort is expended? Sure, one follows the other, except when using code generators. But I always think about the contractor who's going to come along after me to maintain the system - I don't want to leave a bloated implementation, whether I have to write the code myself or not.


December 12. 2007 13:08
Jacob
@Gabriel: Absolutely. If you are programming against a specific requirement, YAGNI has nothing to do with it. You could theoretically argue with the client about how often people who say they're going to migrate to a different DB actually do migrate, but that's subject to all kinds of caveats about your relationship and other specifics of the conversation (like having an uncommonly resolute client). Any time you're facing a client requirement, YAGNI doesn't even enter the picture because YGNI by definition.


December 16. 2007 20:00
Jim
Jacob,
I agree that we should be pragmatic and not dogmatic when it comes to patterns.

However, my main concerns with using TypeMock are as follows. Firstly, if I use the free version, I have to use strings to define my expectations. I find this counter productive if I need to rename or refactor. Secondly, if I want to use the NaturalMock(tm) module of TypeMock, then I have to pay quite a decent sum for it (~$350USD per dev?) . Since excellent tooling (RhinoMocks)exists already for nothing, I'd say thats a significant cost benefit in its own right. I dont mind that Rhino encourages a DI pattern for separation of concerns; it is a valid pattern for doing so, and a DI container is not necessary in all cases. For those who want to use the Service Locator pattern *and* Rhino Mocks, you can provide two constructors to a class you wish to mock, the default using Service Location, and one using constructor injection for testing. Mark the injected constructor as internal, and use the InternalsVisibleToAttribute for test code.

I would prefer a hidden extra ctor over hard coded strings in tests anyday. Both are compromises, but one effect 'refactorability', and one doesn't.


December 18. 2007 13:31
Jacob
@Jim: While using direct typing is to be preferred over using strings, it's not enough to provide an automatic win for Rhino IMO. You lose me with the implied absolute you conclude with: "anyday" can be read as a way of saying "no matter what" and that just doesn't fly with me. I end up asking myself how often it is that I would actually use that better refactoring and for me, the answer is "practically never".

Comments are closed

Information

    Recent Posts

    Calendar

    <<  September 2010  >>
    MoTuWeThFrSaSu
    303112345
    6789101112
    13141516171819
    20212223242526
    27282930123
    45678910

    View posts in large calendar
    Disclaimer
    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2010 Scruffy-looking Cat Herder