InfoQ

News

Does Dependency Injection pay off?

Posted by Niclas Nilsson on Dec 08, 2007 12:16 PM

Community
.NET,
Architecture
Topics
Artifacts & Tools,
Unit Testing,
Design,
Programming
Tags
Best Practices,
Dependency Injection,
Mocks

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?

23 comments

Reply

About YAGNI by Gabriel Lozano-Moran Posted Dec 8, 2007 12:47 PM
Re: About YAGNI by Elisha Ezeugoh Posted Dec 8, 2007 7:14 PM
Re: About YAGNI by zqu dlyba Posted Dec 10, 2007 1:11 AM
headache... by Baron Davis Posted Dec 8, 2007 12:47 PM
DI in Plone by Kevin Teague Posted Dec 8, 2007 3:33 PM
Re: DI in Plone by Sadek Drobi Posted Dec 8, 2007 4:19 PM
Re: DI in Plone by Baron Davis Posted Dec 8, 2007 5:34 PM
Re: DI in Plone by Kevin Teague Posted Dec 8, 2007 6:37 PM
Re: DI in Plone by Jeff Santini Posted Dec 12, 2007 9:44 AM
Loose coupling is one thing, generalizing before there is 'pull' is another by Amr Elssamadisy Posted Dec 8, 2007 4:30 PM
Re: Loose coupling is one thing, generalizing before there is 'pull' is ano by Frédéric TU Posted Dec 12, 2007 3:03 AM
To me it's pretty simple by Bruce Rennie Posted Dec 9, 2007 5:43 PM
Re: To me it's pretty simple by Niclas Nilsson Posted Dec 11, 2007 4:11 AM
RE: Does Dependency Injection pay off? by Andrew Clifford Posted Dec 10, 2007 11:54 AM
Re: RE: Does Dependency Injection pay off? by CH Lee Posted Dec 24, 2007 5:11 PM
Re: RE: Does Dependency Injection pay off? by CH Lee Posted Dec 24, 2007 5:17 PM
Yeah, right! by Steven Devijver Posted Dec 10, 2007 12:26 PM
constructors, not static typing by Steve Tekell Posted Dec 14, 2007 11:11 AM
Designing for testability by Ole Friis Posted Dec 10, 2007 1:37 PM
The one-word DI framework by Darren Hobbs Posted Dec 12, 2007 8:26 AM
Re: The one-word DI framework by Steven Devijver Posted Dec 12, 2007 9:28 AM
Re: The one-word DI framework by Jeff Santini Posted Dec 12, 2007 9:57 AM
Frameworks by Larry Singer Posted Dec 14, 2007 12:38 AM
  1. Back to top

    About YAGNI

    Dec 8, 2007 12:47 PM 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?

  2. Back to top

    headache...

    Dec 8, 2007 12:47 PM 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...

  3. Back to top

    DI in Plone

    Dec 8, 2007 3:33 PM 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 ...

  4. Back to top

    Re: DI in Plone

    Dec 8, 2007 4:19 PM 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.

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

  6. Back to top

    Re: DI in Plone

    Dec 8, 2007 5:34 PM 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.

  7. Back to top

    Re: DI in Plone

    Dec 8, 2007 6:37 PM 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.

  8. Back to top

    Re: About YAGNI

    Dec 8, 2007 7:14 PM by Elisha Ezeugoh

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

  9. Back to top

    To me it's pretty simple

    Dec 9, 2007 5:43 PM 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.

  10. Back to top

    Re: About YAGNI

    Dec 10, 2007 1:11 AM by zqu dlyba

    If in doubt, leave it out - Josh Bloch

  11. Back to top

    RE: Does Dependency Injection pay off?

    Dec 10, 2007 11:54 AM 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.

  12. Back to top

    Yeah, right!

    Dec 10, 2007 12:26 PM 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.

  13. Back to top

    Designing for testability

    Dec 10, 2007 1:37 PM 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...

  14. Back to top

    Re: To me it's pretty simple

    Dec 11, 2007 4:11 AM 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: http://www.rgoarchitects.com/nblog/2007/08/08/DependencyInjectionRevisited.aspx 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

  15. 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!

  16. Back to top

    The one-word DI framework

    Dec 12, 2007 8:26 AM 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.

  17. Back to top

    Re: The one-word DI framework

    Dec 12, 2007 9:28 AM 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.

  18. Back to top

    Re: DI in Plone

    Dec 12, 2007 9:44 AM by Jeff Santini

    Care to elaborate? What is so interesting about it?

  19. Back to top

    Re: The one-word DI framework

    Dec 12, 2007 9:57 AM 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.

  20. Back to top

    Frameworks

    Dec 14, 2007 12:38 AM 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.

  21. Back to top

    constructors, not static typing

    Dec 14, 2007 11:11 AM 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" http://gbracha.blogspot.com/2007/06/constructors-considered-harmful.html 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.

  22. How about Spring for .NET? http://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:)

  23. 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? http://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:)

Exclusive Content

Typemock: Past, Present and Future

Eli Lopian of Typemock answers a few questions on Typemock origins and where Typemock is headed.

Agile in Practice: What Is Actually Going On Out There?

Scott Ambler talks about actual data resulting from surveys made during 2006-2008, showing how Agile is perceived and implemented within organizations.

Building Smart Windows Applications

From QCon 2008, Daniel Moth presents on using Visual Studio 2008 and .NET 3.5 to create compelling rich Windows applications.

Joshua Kerievsky about Industrial XP

Joshua Kerievsky, founder of Industrial Logic, talks about Industrial Extreme Programming which extends XP by including practices dealing with management, customers and developers.

Jeff Barr Discusses Amazon Web Services

Amazon Web Services (AWS) Evangelist Jeff Barr discusses SimpleDB, S3, EC2, SQS, cloud computing, how different Amazon services interact, origins of AWS, AWS globalization and the March AWS outage.

More Than Just Spin (Up) : Virtualization for the Enterprise and SaaS

Cloud services have helped bring virtualization to the forefront. Its full power however, also includes other benefits such as high availability, disaster recovery, and rapid provisioning.

Ruby Beyond Rails

John Lam talks about his path to dynamic languages, some of the problems of making IronRuby run fast, and how the DLR helps with implementing languages.

VMware Infrastructure 3 Book Excerpt and Author Interview

VMware Infrastructure 3: Advanced Technical Design Guide and Advanced Operations Guide provides a wealth of practical insights into setting up virtualization in todays corporate environments.