So… You’re a Java programmer? Or .NET maybe? Do you use dependency injection?
No, seriously. Why? Think about that for a moment. Why are we going through the motions of defining boilerplate interfaces named Iu003cemu003eu0026lt;real name hereu0026gt;u003c/emu003e, with sole inheritors called u003cemu003eu0026lt;real name hereu0026gt;u003c/emu003eImpl.u003csupu003e1u003c/supu003e Why do we sprinkle our code with annotations and configuration, destroying the traceability in the process? Why not just define the real thing once and be done with it?rnrnMVC isn’t a reason: It’s perfectly valid to let your REST endpoints instantiate its services directly. Your code would even be strongly typed again instead of @Randomly typed.u003csupu003e2u003c/supu003e You would once again, for the first time in u003cemu003etwenty yearsu003c/emu003e, directly know where your implementations were coming from! You would need no longer wade through six layers of generated proxy-objects, ballooning your stack track traces to ridiculous proportions. Still we all accept this crapu003cemu003e,u003c/emu003e and more, giving up parts of our precious type system to boot. We might as well be writing in Rub… no, sorry, got carried away there. But still.rnrnAnd if you answered with ‘inversion of control’, I will ask you again: Why? Because IoC is a means to an end, not a goal in and of itself. IoC is nothing more than separation of construction and execution. Those who do the wiring, don’t do the doing. So, seeing how much it costs us to get this off the ground u002du002dcreating huge frameworks in the processu002du002d it had better yield something very valuable. But what? What is so precious and unique that we are all willing to give up so much to achieve it, and do the thing that developers hate most: u003cemu003eextra worku003c/emu003e?rnrnSome honest people might say: u0022We use it because everybody doesu0022. And they’d be right. Everybody does it. It is the norm to ‘do’ IoC. You needn’t even think too much about it anymore. It is so obvious to start a project using a template, getting all those nifty frameworks configured for ‘free’ and steamrolling us into an MVC-layered, dependency injected structure. More often, the project is already under way when we join and we just go with the flow. Which is not necessarily a bad thing, mind.u003csupu003e3 u003c/supu003eAnd so, following the iron laws of group think, we stopped wondering what we are doing and just do.rnrnMost of us, of course, do know the reason behind all this madness. Decoupling. The holy grail of any architecture. We know it is important, because…rnrnAnd this is where it gets weird for me. Once it’s time for the practical examples illustrating the usefulness of decoupling, many dependency injection examples resort to use cases describing some far off doom scenario that happens at most only once in an application life cycle. When you replace your database layer… If your API suddenly changes… Say what? Why do you need to resort to such draconian examples? Is decoupling so abstract that its benefits are only apparent at application scope?rnrnIt’s like decoupling got in with the bad crowd and DI tags along. It tarnished its ideals and sold the family jewels to get the laugh at the party. u0022You heard about the idiot who couldn’t change from Oracle to Postgres? Well, if only he’d decoupled…u0022u003cemu003e u003c/emu003eRecently, a line of similarly weird reasoning popped up: u0022If you want to migrate to microservices…u0022 Which is essentially the same thing.rnrnViewed against these use cases, dependency injection suddenly does seem like too much of a hassle! I can’t defend a daily, continual effort for something that might someday happen once. Neither should you.rnrnYet our use of IoC mirrors this pattern closely. We only @Inject our services into other services, @Autowiring @Singleton into @Singleton ad nauseum. And we restrict ourselves. Only the big stuff gets injected; repositories, services and facades. It seems that if it does not represent a Model, a View or a Controller, it will not get the benefit of IoC. Why is that?rnrnDecoupling isn’t some grand scheme that happens to applications only, but to packages. Classes. u003cemu003eMethods even.u003c/emu003e Every time you invoke a polymorphic method on an interface, you make use of decoupling. Decoupling allows us to shield our changes u003cemu003ehereu003c/emu003e from our critical sub system u003cemu003ethereu003c/emu003e, creating independence and adding a measure of safety. It helps us avoid domino bug chains and post-midnight goose chases through our code base.rnrnDecoupling is about the small, daily separation of responsibilities and our dependency injection should support that. I will talk about achieving this small scoped injection in my next post. Until then, ask yourself: Why are we using dependency injection again?rnrnu002du002du002du002du002du002drnrnu003csupu003e1u003c/supu003e Have you ever really tried to pronounce Impl? It sounds ridiculous.rnrnu003csupu003e2u003c/supu003e Do you remember the promise that annotations would eliminate stringly typed code? Well, @They [Did]. Aren’t you glad?rnrnu003csupu003e3u003c/supu003e Except for the not-thinking part. That is always a bad thing.