Dependency Injection Inversion Rejection
Posted by Davy Brion on January 19th, 2010
Uncle Bob has done it again. In his latest post, he actually advises people to go back to manual dependency injection instead of relying on a framework (our beloved IOC containers) to do it for us. You really ought to check out the post and his examples in particular. Done with that? Ok.
There are two major problems that i have with his post. The first is this one:
I like this because now all the Guice is in one well understood place. I don’t have Guice all over my application. Rather, I’ve got factories that contain the Guice. Guicey factories that keep the Guice from being smeared all through my application.
What’s more, if I wanted to replace Guice with some other DI framework, I know exactly what classes would need to change, and how to change them. So I’ve kept Guice uncoupled from my application.
For those of you who don’t know, Guice is an IOC container from Google. Uncle Bob doesn’t want references of an IOC container spread out throughout his application, but he doesn’t seem to mind coupling his factories with his IOC container for some reason. He seems to think that he can actually switch to a different container more easily because of this, because he would only have to modify his factories.
Here’s the deal. If you have more than a handful of references to your IOC container in your code (apart from the registration obviously), then you really don’t know what using an IOC container is all about. Yes, i know Uncle Bob is supposed to be a legend. Yes, i realize that i’m saying that a legend in the OO world doesn’t seem to grasp some of the most important concepts of using an IOC container. Can you really disagree with that after reading his post?
His whole idea of making it easier to switch to another container with his approach is ludicrous. He would have to modify every single factory that he uses, and in his trivial non-real world examples that wouldn’t be a lot to do but out here in the real world, we’d end up with a boatload of those factories and they would all have to be modified. Conversely, if you’re using an IOC container in the way it is meant to be used, you’d only have to change your registration code and the one or two places where you resolve something manually through the container. And that’s it. Yes, you typically only need one or two places where you use the container directly. Well, unless you’re Uncle Bob of course.
My other problem with his post is with the sample that he uses. It really is a very simplistic example and the approach he outlines simply does not scale when you’re dealing with large, real-world codebases. His approach might work for the size of the examples in his books, or for the code of Fitnesse, but if i were to apply his recommended approach for some of the systems that we’re working on, it would lead to a terrible mess very quickly. Not exactly what i’d have in mind when thinking of Clean Code.
The one thing i do like about this post? Well, there are quite a few people who follow Uncle Bob blindly and can’t say a single bad thing about his thoughts/ideas/approaches. I know quite a few of them make extensive use of IOC containers and some of them are even involved in the development of these containers. Hopefully, Uncle Bob’s post will finally convince these people that blindly following anyone is simply never a good idea and that you have to keep a critical mindset for everything that you read, no matter who wrote it.

January 19th, 2010 at 11:43 am
Agree! Also read his post and using StructureMap my self and the only place where I do any IoC-stuff is in my registry classes and some bootstrapping.
January 19th, 2010 at 12:55 pm
I agree as well. Jimmi Bogard had a similar response (http://www.lostechies.com/blogs/jimmy_bogard/archive/2010/01/18/poor-use-of-di-versus-need-for-di.aspx)
January 19th, 2010 at 2:48 pm
Davy,
well – I was really one of the first people to comment on his post (http://twitter.com/kkozmic/statuses/7873032098)
I don’t want to sound like one of these people who follow Uncle Bob blindly, as you described it, but I would give him benefit of a doubt.
The way I see it (I don’t know guice beyond what he shows in the post) – he’s just working with pretty basic container, which does not offer things that .NET container do (what I alluded to in my 140chars tweet). There’s no batch registration, no conventions based injection. It’s .NET 2003 IoC. We were doing the same thing in 2003, and if anything, I treat this post as a testament of how .NET IoC tools are ahead of Java.
January 19th, 2010 at 2:50 pm
[...] Several people have reacted to a controversial post by Uncle Bob on that topic with, among the most vocal ones, Davy. [...]
January 19th, 2010 at 2:52 pm
@Krzysztof
dismissing a practice almost in its entirety based on one bad IOC container or some people’s bad usage of it is completely unprofessional, irresponsible and i’d even say ignorant
He should realize that many people will take his advice and run with it. When that advice is based on faulty data (the ‘bad’ IOC container, or the ‘bad’ usage of some people), there’s quite a bit of damage being done which essentially doesn’t help _anyone_
January 19th, 2010 at 4:58 pm
Being relatively new to the whole IoC container thing (started experimenting with Castle Windsor based on one of your posts), I was wondering if you could maybe comment a bit more on your the use of your container..
You write in your post
” … you’d only have to change your registration code and the one or two places where you resolve something manually through the container.”
Now, as I said I am still new to IoC containers, so this may be a stupid question, but could you give some examples of how to achieve this goal of one or two manual resolves to the container? In the Website I am writing at the moment I seem to have quite a few manual resolves compared to your statement… I am using ASP.NET (but not MVC unfortunately)..
Regards,
Morten
January 19th, 2010 at 5:44 pm
@Davy – totally on the same wave length…
People seem to think that using an IoC is going to reduce explicit code complexity, it doesn’t (well may be StructureMap does with it’s fluent candy). It’s better to centralise your thinking around object life in a central location than have it splintered and spread around multiple factory classes.
My current project is exactly as you describe a central registry and we specifi bootstrappers for WCF, NH and HTTP handlers.
Awkward Coder
January 19th, 2010 at 7:50 pm
@Morten
in the case of WebForms, we did something like this:
have each page inherit from your YourProjectPage. YourProjectPage has a generic type parameter of TPresenter (or TController of whatever you want to call it). The constructor of YourProjectPage resolves the TPresenter (or TController) in its constructor and all of its dependencies will be supplied by the IOC container. And that’s it… one Resolve statement in your entire Web Application.
In the case of a service layer, either use Castle’s WCF facility to automatically resolve your service instance, or use something like Agatha which does it for you. When the request is received in your service layer, there is essentially one resolve being executed by the container which gives you the component to handle the request. And obviously, all of its dependencies (and their dependencies, etc…) will be fulfilled.
January 19th, 2010 at 10:23 pm
I think the factory idea has a lot more legs than you give it credit for. I’m afraid my justification of that ran to four pages.
http://www.colourcoding.net/Blog/archive/2010/01/19/dependency-reversi.aspx
January 20th, 2010 at 1:33 am
The thing I don’t understand is why Uncle Bob wouldn’t just put a layer over his IoC container so that it is truly invisible to the rest of the application. Wouldn’t that be the ideal approach rather than ditching the container altogether?
January 20th, 2010 at 8:50 am
@Julian
i’m gonna reply to that post later on
@Will
you don’t really need to put a layer on top of it… that’s only useful when you’re writing a framework/library which needs to be able to support multiple containers but for most applications, it’s unnecessary. Again, if you want to switch containers it should only be a very minor change in very few places. Unless of course, you’re using very specific features of a certain container that aren’t supported by other containers. But in that case, a layer on top of it wouldn’t give you any benefit either.
January 20th, 2010 at 9:10 am
The question is why somebody wants to change his IoC container anyway? To me an IoC frmaework is like the system backbone (because most of IoC frameworks are Application frameworks too) We use Castle in our projects and I can’t imagine that we can live without it for a second.not only it’s our IoC container but we are using it to intercept our code using DynamicProxy to manage our transactions using NHibernate and Transaction facilities.
January 20th, 2010 at 9:14 am
@Nima
Yeah i kinda agree with that… something really bad would have to happen before i’d want to switch containers in one of our projects. The whole thing about switching containers during the lifetime of a project is very similar to how people talk about being able to switch ORM’s during the lifetime of a project. A lot of people say they want to be able to do that, while in reality hardly anyone actually does it.
January 20th, 2010 at 11:54 am
[...] Dependency Injection Inversion Rejection – Davy Brion picks up on some of the points in Uncle Bob’s recent post on Dependency injection mostly discussing the flip side of the pointsand how the suggested usage still causes too much coupling to the container. Jimmy Bogard also follows up on the same topic with his post Poor use of DI versus need for DI. [...]
January 20th, 2010 at 6:37 pm
I would have to say that there are very valid reasons for moving the code which “touches” the IoC into a factory. I can value centralizing this code in one place because, quite frankly, if you’ve got a lot of code touching the IoC, you’re doing it wrong. In my case I can see definite value to wanting the IoC to be swappable as well. From one client to the next, I have found that I very rarely use exactly the same set of components. Usually this is because client “A” was already using StructureMap, client “B” was already using Ninject, and the new client “C” has a “Microsoft by default” mentality which mandates Unity. As a result, I try to isolate ALL such dependencies on external tools whenever it’s practical, just so that I can reuse as much of my reference code as possible.
January 21st, 2010 at 3:05 pm
[...] Dependency Injection Inversion Rejection | The Inquisitive Coder – Davy Brion’s Blog [...]
January 23rd, 2010 at 4:23 pm
[...] Dependency Injection Inversion Rejection [...]