I’ve been giving poor Nate Kohari a hard time over at Discord & Rhyme. He has been very patient in Defending Dependency Injection. His attitude stands in sharp contrast to Ayende Rahien's post today about testing Linq for SQL. Ayende’s snide "(Best Practices, anyone?)" is exactly the attitude I lamented in my original post on Dependency Injection when I said
I do wish that people would admit that DI doesn’t have compelling applicability outside of Unit Testing, however. I’m reading articles and discussions lately that seem to take the superiority of DI for granted. And I’ve read mock object examples that seem a little bit condescending about dependency injection—as if your projects should already incorporate this technique.
I find myself reflecting more and more on how liberating TypeMock is and come back to wondering again if Dependency Injection would exist as a pattern at all if it weren’t for unit testing.
My hypothesis (entirely untestable, so technically a mere speculation) is that what happened is that in order to achieve 100% code coverage in their unit tests with methods that read databases or call web services or have other potentially nasty dependencies, someone came up with the neat idea to invert control of those dependencies so that unit tests could feed in an abstracted object that fakes those calls and the real logic of the methods could be tested without bothering the poor database (or whatever). That’s a noticeable, pervasive, broad architectural change, though, especially if it is only used for unit testing, so in order to defend their idea, developers began looking for additional justification for this pattern. Since nobody but Microsoft uses providers (and that really only in Asp.Net) and software factories are so last year, they cannibalized the strengths of both and pushed them down to the object level and called it done. I’m not saying they did so maliciously or dishonestly. I’m just saying that they needed further justification and that the justifications they chose are already served by applying other useful patterns.
Seriously, with providers that allow you to contextualize defined sub-systems and something that allowed you to Mock objects in testing without having to feed those objects to the tested class, can you think of a good reason to use Dependency Injection? Any dependency that needs to be altered more frequently than a contextual provider framework would allow needs to be exposed for access by calling objects anyway, I’m thinking.
This thinking was crystallized as I explored some of the DI frameworks referenced by Nate. As I watched Kevin Bourillion and Bob Lee explain their Guice for Java framework (a DI framework created by Google), I was struck by the number of references to testing. From that presentation alone, it looks like the main impetus for Guice was unit testing and the other benefits described would have been as easily satisfied with a provider framework.
Come to that, it could be that solid DI frameworks like Guice and Castle Windsor have a niche when it comes to making providers easy to create, control, and use.
Still and all, I wonder what would have happened if they had invented something like a Java version of TypeMock for their mock objects first.