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.