BT
x Your opinion matters! Please fill in the InfoQ Survey about your reading habits!

Does Dependency Injection pay off?

by Niclas Nilsson on Dec 08, 2007 |

There has been an interesting discussion in the blogosphere about the benefits or lack of benefits from using dependency injection (DI).

The discussion started with Jacob Proffitt writing a blogpost where he explains that in his opinion, dependency injection doesn’t scale well. According to Proffitt, the only reason DI is popular is because of mocking.

The real reason that DI has become so popular lately, however, has nothing to do with orthogonality, encapsulation, or other “purely” architectural concerns. The real reason that so many developers are using DI is to facilitate Unit Testing using mock objects. Talk around it all you want to, but this is the factor that actually convinces bright developers to prefer DI over simpler implementations.

Proffitt goes as far as claiming that DI is only good for unit testing:

I do wish that people would admit that DI doesn’t have compelling applicability outside of Unit Testing, however.

However, Proffitt does use unit testing, but without DI. He is using a the TypeMock framework, which is able to intercept calls to dependencies even if they are created inside the code under test. This means that Proffitt doesn’t have to decouple his objects to be able to create mocks for his unit tests.

Ayende, the creator of RhinoMocks, responds in his blog:

While the ability to easily mock the code is a nice property, it is almost a side benefit to the main benefits, which is getting low coupling between our objects. I get to modify my data access code without having to touch the salary calculation engine, that is the major benefit I get.

Nate Kohari also answered to Proffitt’s initial post. After showing a DI code example, Kohari elaborates on what DI really is:

If you’re a GoF fan, this is actually the Strategy pattern. Dependency injection (in my perspective) is basically the Strategy pattern used en masse.

Kohari is the creator of the NInject DI framework, and he pushes the usefulness of DI frameworks:

Once you start writing code that relies on a DI framework, the cost required to wire objects together falls to next to zero. As a consequence, hitting the goal of Single Responsibility becomes exponentially simpler.

In a later post, Kohari responds to Proffitt’s original claim that DI does not scale, by restating the importance of using a framework:

In real-world scenarios, dependency injection by hand simply does not scale.

Proffitt does not agree:

How can you say that dependency injection (I’m not taking on the whole inversion of control pattern, but I might. Jury’s still out on that one.) creates loosely coupled units that can be reused easily when the whole point of DI is to require the caller to provide the callee’s needs? That’s an increase in coupling by any reasonable assessment. Dumping the coupling workload onto a framework doesn’t change the fact that it’s still a requirement to supply external stuff to use an object.

Kohari explains that in most cases, in his configuration he only needs to set up how to create and inject a certain type of object once and that it is not done by the caller but by the framework.

Kohari also talks about changeability of the code:

… simply put, dependency injection makes your code easier to change. That’s why it’s so popular in Agile crowds, whose whole software development practice is geared around quick alterations in path.

Eli Lopian, CTO of the company that created TypeMock, enters the debate with a few argument that defines the core of the debate:

When you use DI as a ’Silver Bullet’ you are losing more then half the abilities of your programming language. You can not use static methods or the ‘new‘ keyword or sealed types. Oh, you have to make all your methods virtual too.

He also argues that using DI just to enable change violates the YAGNI principle.

Lopian continues:

One of the first issues that was discussed when TDD was starting was: “should we change our code to make it testable?” Should we change the visibility of our code? Should we change the design of our code? This lead to a collision between testable code and OO encapsulation. Developers started to expose private parts of the code to enable testing. It started with private fields and methods and now it is the complete design.

This is the classic part of the discussion. Some people argue that changing the code to make it more testable is a good thing, others argue that breaking encapsulation for that reason is a bad thing.

Kohari’s take on encapsulation and dependencies is:

Here’s the secret that makes dependency injection worthwhile: when it comes to dependencies, encapsulation is bad.

If changes made for unit testing purposes leads to looser coupling (which itself is questioned by Proffitt) - is this a good thing or not?

Both loose coupling and encapsulation are valued OO properties, but how shall we handle the balance? Which is the right path?

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

About YAGNI by Gabriel Lozano-Moran

YAGNI is about not wasting precious time on features that might change in future iterations. If you anticipate on 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. Strictly taken even using methodologies like Extreme Programming could be considered a violation of the YAGNI principle as well because who says that your project is going to need XP to be successful?

headache... by Baron Davis

Reading the comments from guys against DI was such a waste of time. Everyone can critize what already exists, if they think it is bad go create something that is better than DI so I can:
-at app bootstrap time wire all objects on heap automatically
-hot deploy new component (object graph) without restarting running system by just dropping Spring XML with reference to parent factory and everything is automatically wired.

If you dont have better solution, and if you are not bringing something new and useful to the table, dont bother posting.

Oo wait, they didn't post it here...

DI in Plone by Kevin Teague

Silly post. Of course dependancy injection can be used to great benefit. The Zope Component Architecture is the DI framework I've been using. When Plone made the migration to this, it become a *lot* easier to make significant customizations to the system without having unexpected changes cascade to unwanted places. Code re-use is also a lot easier to achieve in a DI framework. Just because some people have used DI poorly means that the technique is bad ...

Re: DI in Plone by Sadek Drobi

I really do not understand why people get so hostile when reading something that doesn not match their point of view!
A very interesting debate in my opinion.

Loose coupling is one thing, generalizing before there is 'pull' is another by Amr Elssamadisy

If you are using a framework like Zope, there is pull for making things configurable.

If you are not writing a framework, then when do you generalize? Always? Never?

So, based on design criteria - when do *you* generalize? It could be:

1) Always,
2) Whenever I put something under test,
3) Whenever there is more than one implementation of the same interface,
4) More than 2 usages....

As for me, I usually go with (4) and sometimes (3), but that's just me.

Re: DI in Plone by Baron Davis

OK ok my apologizes, the tone was kind of rude.

However, this article is same as if I was drowning in the water, and someone is describing me what water is instead of helping me or bringing solution so I dont drown now or I dont fall in water in the future.

I'm out.

Re: DI in Plone by Kevin Teague


I do wish that people would admit that DI doesn’t have compelling applicability outside of Unit Testing, however.


I think there is just strong disagreement with that idea. DI has been used in systems that predate a strong emphasis on unit testing, and has been used by people who were either unaware of or are not practicing unit testing. I know that I've also thought of DI as a technique for allowing implementations to be selected based on external data, and that being able to use mocks in testing was only an interesting side effect.

Re: About YAGNI by Elisha Ezeugoh

Interesting take on things. But I suppose one can make that argument about almost any new tool, framwork or technology.

To me it's pretty simple by Bruce Rennie

The problems that I encounter if I "overuse" DI aren't really a major headache for me. On the other hand, what happens if I don't unit test things thoroughly actually causes me pain. Debate over.

Re: About YAGNI by zqu dlyba

If in doubt, leave it out - Josh Bloch

RE: Does Dependency Injection pay off? by Andrew Clifford

This is a really interesting take on DI. Only late did I realize this was a .Net-centric view. My reaction is that, well ofcourse, if it isn't baked into Visual Studio and/or Microsoft doesn't bless the design-centric approach then yeah you may only see the benefit of DI in unit testing.

On the java-centric side, DI, or more specifically, the springframework.org implementation of DI, helped a lot of systems and projects to get away from the heavy single blessed framework of EJB. Designing became easier allowing you to separate business concerns from system concerns. Portability went up, TCO went down, and yeah the use of unit testing became easier.

To hear this .Net-centric view makes me feel sorry that .Net users have so little community and innovation outside of the MS suite of tools. I know, sounds condescending, but I can't see risking my career on one vendor's offering. DI in .Net land is only a symptom to a deeper business not architectural problem.

Yeah, right! by Steven Devijver

It's an interesting discussion. Just as interesting as asking oneself: shall I wear underwear or shall I try something really nifty today?

DI is the best friend of statically typed, object-oriented languages (Java, C#, ...). Yet it's been proven that even in dynamically typed, object-oriented languages DI can be very important (Plone, Grails, ...).

To doubt DI is important or useful is to say: I've never built any seriously complicated application in my life. That's OK by the way.

DI has to be tamed like any other programming feature in the hands of developers.

Designing for testability by Ole Friis

Interesting discussion. Thanks!

I'm a bit puzzled about the argument that designing for testability is bad. In my experience, systems designed for testing are easier to comprehend since they are better split up in modules with clearly-specified responsabilities.

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. Besides, setting up DI is not going to take more than a few minutes of your time...

Re: To me it's pretty simple by Niclas Nilsson

@Bruce - I agree, and it seems like most people in the original debate agrees too, but the users of a particular framework have found a way to do unit testing (mocking) without DI. I didn't interpret their arguments as if they were skipping testing.

Arnon Rotem-Gal-Oz is explaining how to do the sam trick in dynamic languages (Ruby in this case) here: www.rgoarchitects.com/nblog/2007/08/08/Dependen...

In a dynamic language, you don't need a framework like TypeMock to do the same thing, so this sharpens the question even more. Is DI good in itself (in any environment) or is it unnecessary if you can mock away dependencies for testing. Steven Devijver's comment in this thread is interesting from that point of view.

The question: Is DI a way of desining your software that has a value in itself or not - regardless of testing.

/Niclas

blog: niclasnilsson.se

Re: Loose coupling is one thing, generalizing before there is 'pull' is ano by Frédéric TU

This debate is quite interesting, specially your comment.

DI should be use everywhere (there was a time where some colleage propose to encapsulate Value Object behind interface to have change to change it or to hide method).
That's a little bit too much.

Anyway there are some crutial point to use DI. Have you ever think that opening ressource and using it can be something from different concern?

If you seperate the concern in two classes that means that you have to manage TWO class to operate ONE fonctionnality, DI won't bring anything.

But when it comes to big project where you may open many time ressources to your environnement, it may be usefull to externalise the fact of CREATE an endpoint of a ressource and USING it to create fonctionnality.

I use DI specially to seperate technical code and business code (which should be polute with technical code), and make it all more readable!

The one-word DI framework by Darren Hobbs

My favourite DI framework is just one word: 'new'. The whole XML-driven edifice that is Spring DI and friends seems like little more than an aversion to writing objects with sensible constructors and calling 'new'. Using XML configuration to perform tasks that should be done in code loses all the benefits of compile time checking and type safety for no gain. Changing something as fundamental as which implementation of an interface you choose to instantiate should not be done to a deployed system without going through a continous integration (build/test/deploy) cycle, so the only real 'benefit' of XML based DI is actually a risk.

Re: The one-word DI framework by Steven Devijver

1/ DI is not about XML.

2/ Even if you're using XML, it's not about changing the configuration of deployed application.

One of the purpose sof DI is to write better and especially less code.

Re: DI in Plone by Jeff Santini

Care to elaborate? What is so interesting about it?

Re: The one-word DI framework by Jeff Santini

Darren is not suggesting to avoid DI, he is suggesting to avoid XML configured DI. If I reduce the amount of "code" I write and replace it with equal amounts of XML where is the benefit? Many of us here recognize the benefits of DI, but what good does throwing all your DI config into XML do when you could just as well have your config in C# or java which brings the benefit of compile time type checking.

Frameworks by Larry Singer

Jacob Proffitt said (in the comments):

... the whole point of DI is to require the caller to provide the callee’s needs ...


This is where he got it wrong. The whole point is to outsource the supply of those needs to the framework. The caller doesn't need to know anything about creating the callee, all it needs to know is how to use it. It says to the framework I need one of these and the framework gives it one.

constructors, not static typing by Steve Tekell

The main problem DI solves isn't about static versus dynamic typing, but about constructors.
Check out Gilad Bracha's "Constructors Considered Harmful"
gbracha.blogspot.com/2007/06/constructors-consi...

So while Groovy, for example, brings dynamic typing to the JVM, it still creates objects like Java. So you expect to find DI being used.

Re: RE: Does Dependency Injection pay off? by CH Lee

How about Spring for .NET?
springframework.net/
Though I don't think it's popular.........

Also NUnit is pretty good that JUnit team took some idea from it. I personally like to be technology-agnostic and believe good ideas should be leveraged whenever possible.

My 2 cents:)

Re: RE: Does Dependency Injection pay off? by CH Lee

This is a really interesting take on DI. Only late did I realize this was a .Net-centric view. My reaction is that, well ofcourse, if it isn't baked into Visual Studio and/or Microsoft doesn't bless the design-centric approach then yeah you may only see the benefit of DI in unit testing.

On the java-centric side, DI, or more specifically, the springframework.org implementation of DI, helped a lot of systems and projects to get away from the heavy single blessed framework of EJB. Designing became easier allowing you to separate business concerns from system concerns. Portability went up, TCO went down, and yeah the use of unit testing became easier.

To hear this .Net-centric view makes me feel sorry that .Net users have so little community and innovation outside of the MS suite of tools. I know, sounds condescending, but I can't see risking my career on one vendor's offering. DI in .Net land is only a symptom to a deeper business not architectural problem.

How about Spring for .NET?
springframework.net/
Though I don't think it's popular.........

Also NUnit is pretty good that JUnit team took some idea from it. I personally like to be technology-agnostic and believe good ideas should be leveraged whenever possible.

My 2 cents:)

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

23 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2014 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT