Los Techies : Blogs about software and anything tech!

Poor use of DI versus need for DI


Surprise surprise, but Uncle Bob got the twitterverse all riled up with another opinionated post, “Dependency Injection Inversion”.  His basic advice from the post on DI tools is:

I think these frameworks are great tools. But I also think you should carefully restrict how and where you use them.

Couldn’t agree more!  Every call to Container.GetInstance should be carefully, carefully thought out.  In fact, our goal should be to reduce the number of calls to the container to hopefully exactly one.  But a slight problem with the example he gives to show that DI is not necessary in all cases:  It’s so simplistic that it no longer represents any real-world code using DI.

Uncle Bob also prefers hand-rolled mocks, which may be an artifact of the crappiness of Java mocking tools, which in turn is a reflection of how far behind Java the language is behind C#.  He also points out:

I don’t want lots of concrete [Container] dependencies scattered through my code.

Couldn’t agree more!  That’s why we limit the container calls in our application as much as possible.  If I have a bunch of container calls in my code, I’m doing something wrong.  When I read his post, I thought that they must have been looking at the MVC framework source code, one which was built with IoC hooks, but not with the Dependency Inversion Principle in mind.  If I have to tell MVC that I’m using an IoC tool, it takes quite a bit of work to configure all of the places where things get instantiated manually to work.  I often have to write new classes just to support IoC.  Whether he meant to or not, Uncle Bob’s entire post was a straw man argument.  He argues against bad use of IoC, but never shows good use of IoC.  Which may mean that he’s never built or seen an application built well with IoC.

If you want to see an application written with DIP, IoC and Dependency Injection in mind, check out FubuMVC.  One of its core principles from the get-go was “turtles, all the way down”, basically meaning that a container will be used, and you cannot use the application without an IoC tool.  Guess what?  The design is much cleaner for it.

If I want to use an IoC tool in my application, this is something that should be configured once and only once.  If I have to plug a bunch of hooks just to say, “Yes, I am using an IoC tool”, then I haven’t really improved anything for the end user, have I?  Instead, I’ve made my application favor configuration over conventions, forcing more coding and more moving parts to figure out, making it more difficult to configure as needed.

So while it’s a great read and has a lot of great points, all that post showed me was that poor use of DI leads to a poor DI experience.

Kick It on DotNetKicks.com
Posted Jan 18 2010, 09:19 AM by bogardj
Filed under:

Comments

Chris Nicola wrote re: Poor use of DI versus need for DI
on 01-18-2010 12:02 PM

Agreed, if you are calling Container.GetService or something similar all the time then that really isn't "Injection".  Well, other than the fact that you save satisfying the dependencies of that dependency.

Having a bunch of classes with a dependency on ServiceLocator or some custom IoC static class is definitely a code smell.  You shouldn't need to call on the container anywhere but perhaps in the bootstrapper code.

Heh, I was also mildly surprised at the "hand rolled mocks" preference.  Though both of these comments may be more of a personal preference rather than a reflection on Java.  Some people prefer hand-rolled cigarettes too.

Twitter Trackbacks for Poor use of DI versus need for DI - Jimmy Bogard - Los Techies : Blogs about software and anything tech! [lostechies.com] on Topsy.com wrote Twitter Trackbacks for Poor use of DI versus need for DI - Jimmy Bogard - Los Techies : Blogs about software and anything tech! [lostechies.com] on Topsy.com
on 01-18-2010 12:17 PM

Pingback from  Twitter Trackbacks for                 Poor use of DI versus need for DI - Jimmy Bogard - Los Techies : Blogs about software and anything tech!         [lostechies.com]        on Topsy.com

Peter Ritchie wrote re: Poor use of DI versus need for DI
on 01-18-2010 2:42 PM

I couldn't agree more.  Dependency Inversion is about managing dependencies, about reducing coupling.  I won't beat the dead horse that are the benefits of doing this; but exchanging one coupling for another (changingg a coupling from direct construction of one of your internal classes to use of an inversion container) doesn't get you the full benefit.  Sure, you're now coupled to something more stable; but you're still forcing the responsibility (and thus coupling) of creating these objects via the container on to types that shouldn't have this responsibility.

There should be very little calls to the IoC to create or initialize an object.  You'll need at least one; but if all creation/initialization of your objects involves a direct call into the IoC, you haven't designed for DI; you're simply using a DI container.

unclebob wrote re: Poor use of DI versus need for DI
on 01-18-2010 3:47 PM

A number of people have pointed out that my example was so simple as to be meaningless.  I think that's funny because, I took the example from the Guice tutorial.  In any case, I wrote the post because I have seen a fair bit of code lately that exhibits the problems I was talking about.  The fact that some of us know how to use a DI container does not mean that a vast number of developers aren't out there abusing them.

John Sonmez wrote re: Poor use of DI versus need for DI
on 01-18-2010 5:34 PM

Well balanced response.  I can definitely see your point here.  I will check out FubuMVC.  I have seen a large amount of hard to understand code due to overuse of IoC containers, but that doesn't mean they can't be used correctly.  I think the core problem is we have so many containers and frameworks.  I would like to see a language built around this core idea.

jcteague wrote re: Poor use of DI versus need for DI
on 01-19-2010 12:57 AM

Wow, that was a great article.  You very eloquently described the situation perfectly.

uberVU - social comments wrote Social comments and analytics for this post
on 01-19-2010 1:23 AM

This post was mentioned on Twitter by lostechies: blogged: Poor use of DI versus need for DI: Surprise surprise, but Uncle Bob got the twitterverse all riled up wit... http://bit.ly/5eOiyn

Michael Sevestre wrote re: Poor use of DI versus need for DI
on 01-19-2010 6:42 AM

I totally agree with your article.

There are in my opinion however some valid scenarios where a call to "container.GetInstance()" makes total sense, for example when the instance to retrieve implements IDisposable.

In that case, you do want to dispose the object as soon as you are done with it and construction injection is not enough.

A call would typically be

using(var objectToRetriever = container.GetInstance(IDisposableObject))

{

//do stuff here

}

bogardj wrote re: Poor use of DI versus need for DI
on 01-19-2010 8:30 AM

@Michael

Oh, there are definitely some valid calls to a container.  We have places where we must use a container, especially in infrastructure code that serves as the backbone of certain areas.

den Ben wrote re: Poor use of DI versus need for DI
on 01-19-2010 8:38 AM

unclebob: "A number of people have pointed out that my example was so simple as to be meaningless.  I think that's funny because, I took the example from the Guice tutorial.  In any case, I wrote the post because I have seen a fair bit of code lately that exhibits the problems I was talking about.  The fact that some of us know how to use a DI container does not mean that a vast number of developers aren't out there abusing them."

Examples in a tutorial tend to be simple (easier to grasp the concepts).  I you want to prove DI can go bad you may want to use a more realistic example (as you say... you have seen a fair bit of code lately that exhibits the problems => create an example based on that code)

Still... everything pattern can be used and abused.  Bad DI is bad, good DI is ...?

Jonathan Perret wrote re: Poor use of DI versus need for DI
on 01-19-2010 8:42 AM

@Michael Sevestre : in such a case, shouldn't you take a dependency on an IDisposableObjectFactory instead ?

Every time you take a dependency on the container, you're basically saying that this class may instantiate pretty much any other class, and therefore no longer controlling your dependencies.

It seems in fact that Uncle Bob was railing against this particular kind of "leaks".

Cheers,

--Jonathan

bogardj wrote re: Poor use of DI versus need for DI
on 01-19-2010 11:36 AM

@Jonathan

For those *very few* places where I need a container, I still wind up depending directly on the container, as a dependency.  It's just a personal preference thing...but I just prefer less code, over a facade.

Bill Sorensen wrote re: Poor use of DI versus need for DI
on 01-19-2010 5:01 PM

Excellent response. I agree that this is an (exceptional) case where it's best to respectfully disagree with Uncle Bob.

Jonathan Perret wrote re: Poor use of DI versus need for DI
on 01-20-2010 4:34 AM

Thank you Jimmy for responding.

I'm definitely with all of you on the "less code" argument. But two more points if I may, mainly to clarify my own understanding :

1. When you do need the container, as you said the class takes an explicit dependency on it ("container" constructor arg, perhaps). Very good. So can we all agree that the often seen "IoC" global variable is an anti-pattern ?

2. For the particular case, described above, of a class that must lazily (and/or multiple times) instantiate a class whose type is known at configuration time (i.e. we're not writing a ControllerFactory), when I suggested using a factory I was not thinking of writing it manually (and my hint of a named factory interface was misleading in that respect). What I would actually do in that case is add a Func<IDisposableObject> constructor argument, very easily configured with a lambda that captures the injector as a local variable, like so : ()=>injector.Create<IDisposableObject>()

I believe this keeps the dependencies under control for a modest cost.

Hoping this makes some kind of sense,

--Jonathan

The Morning Brew - Chris Alcock » The Morning Brew #521 wrote The Morning Brew - Chris Alcock &raquo; The Morning Brew #521
on 01-20-2010 5:54 AM

Pingback from  The Morning Brew - Chris Alcock  » The Morning Brew #521

@NeilRobbins wrote re: Poor use of DI versus need for DI
on 01-21-2010 6:03 PM

Interested by your little swipe at Java mocking tools (agree about the lang). I'm not a Java guy (in any way), but I've been very impressed with Mockito (much like Moq), have you seen it? Even JMock has improved a lot over the years and whilst I find it slightly opaque compared to Moq (& mockito) & more of a PITA, I don't think the state of it can properly explain Bob's love for writing his own mocks (too many Kata's creating a strange love of small, simple, pretty things might).

Good response to U.B. though - fully agree with your general sentiment, just intrigued by the mock bit.

Elegant Code » Being provoked by your uncle wrote Elegant Code &raquo; Being provoked by your uncle
on 01-24-2010 10:09 AM

Pingback from  Elegant Code » Being provoked by your uncle

Week @ Lab 2/13/10 « Tech Tock wrote Week @ Lab 2/13/10 &laquo; Tech Tock
on 02-14-2010 7:17 PM

Pingback from  Week @ Lab 2/13/10 « Tech Tock

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems