1. 4
  1.  

  2. 7

    This doesn’t cover the real reason I usually get frustrated with dependency injection: when debugging, it’s usually extremely difficult to understand what code a given method call is actually calling, because there’s four implementers of the interface and the choice of which implementation to use is based on some obscure combination of configuration parameters that are different between prod and my workstation.

    In general, I think DI as a pattern can be good when you have a couple service-level-type things, and you inject those (IDatabaseConnection and the like). But at big Java shops (/me thinks back to Google) people seem unable to resist the urge to smash everything with their DI hammers, so I just try to avoid it at this point.

    1. 3

      I think what you said is an overall problem with subtyping (in objects, at least): you need a lot more context than the code you’re reading to understand what the code does. DI doesn’t help in that it’s a static-analysis black-hole. What’s also frustrating is the whole system is inverted in that you can never really know if two methods that take the same interface are getting the same type or not. In Ocaml we have something called functors which is nice in that they are compile-time and they let you express “hey everyone, where you see a type t now, that is actually an int”. The relationship becomes much clearer.

    2. 4

      I could be wrong, but most of my distaste from DI comes from the fact that if you feel like you need it, it seems like you’ve already way too deep into the Turing Tarpit and need to work on getting out, rather than building a ladder to ease your way down.

      I prefer to architect in terms of components which encompass subsystems. Those subsystems can be configured, but such configuration doesn’t percolate past that point. That way, Main() contains all of the glue code required to make things go. Spreading configuration over the codebase drives me crazy. This probably isn’t very Enterprisey, but, whatever.

      In short: I prefer simple and explicit over super-flexible configurable things.

      1. 3

        In the above example, if you have another class that needs a soap bottle, you’ll have to go through the same motions again, and you’ll end up with lots of code duplication.

        IME the right thing is to solve this problem the way you’d solve any other code duplication problem in your app. Do your wiring up “manually” in regular code and then it’s all just code; make your factories first-class classes and then they’re just ordinary classes.

        Admittedly this is much easier in a language with multiple inheritance or similar functionality, because commonly the factory for A needs the factories for B and C, and if both B and C need D then you don’t want two copies of D.

        1. 1

          Here’s how to do dependency injection in javascript: http://vvgomes.com/javascript-dependency-injection/

          Although the post focuses on javascript, the same approach can be used for other languages like ruby and python…