<story><title>Dependency injection is dynamic scoping in disguise</title><url>http://gustavlundin.com/di-frameworks-are-dynamic-binding/</url></story><parent_chain></parent_chain><comment><author>denisw</author><text>I really enjoyed the comparison of dependency injection with dynamic scoping, and the explanation of how the latter can take over the uses cases of the former with less boilerplate.&lt;p&gt;But one benefit of dependency injection unacknowledged in this article is that dependency injection is the explicitness of dependencies: the need to pass them in forces the caller to be aware of which dependencies exist, and changes in dependencies cannot be ignored (they lead to compilation errors in statically typed languages, at least).&lt;p&gt;Managing dependencies with dynamic variables, on the other hand, is implicit. It&amp;#x27;s impossible to know which parts of the dynamic environment are used by a module without inspecting its source code. And changes to the module&amp;#x27;s dependencies are not noticed by callers, which may lead to cases where tests fail to stub out particular side effects without anyone noticing.&lt;p&gt;Given this drawback, dependency injection still seems like the better trade-off to me, despite of its higher amount of required boilerplate. Perhaps it is possible to bring some of the explicitness to the dynamic scoping approach, though.</text></comment>
<story><title>Dependency injection is dynamic scoping in disguise</title><url>http://gustavlundin.com/di-frameworks-are-dynamic-binding/</url></story><parent_chain></parent_chain><comment><author>cryptica</author><text>I agree that dependency injection and dynamic scoping are similar and I think they are both anti-patterns.&lt;p&gt;It doesn&amp;#x27;t make sense to stub out dependencies in unit tests (unless you absolutely have to). Stubbing out dependencies is like stubbing out native functions, operators or loops. They are called dependencies for a good reason; because your class depends on them and assumes that they work. Trying to make dependencies substitutable is overengineering and leads to poor design and gives you more work when implementing unit tests.&lt;p&gt;Dependency injection is particularly bad because it makes it difficult to find the path to the dependency&amp;#x27;s source code (which is critical for debugging). Hiding the source path of a dependency is a terrible anti-pattern. When it comes to programming, there are few things more horrible than not being able to determine where some buggy piece of logic is located. I cannot imagine any use case where that would be a fair tradeoff.&lt;p&gt;Any kind of injection of dependencies should be done via an explicit method&amp;#x2F;constructor parameter. Sometimes it means that the dependency instance has to traverse a few classes in the hierarchy, but that&amp;#x27;s way better because at least you can unambiguously track where the dependency came from. Also, if the dependency has to traverse A LOT of classes, then you know there is probably something wrong with your architecture (e.g. a dependency imported too high in the hierarchy and used in a deeply nested class can indicate poor separation of concerns and leaky abstraction between components).</text></comment>