1. 13
  1.  

  2. 5

    I feel like the author has a good observation first, but then goes into over the top ridicule. His c# example is complete, there’s no XML to add there. The di is separate from hosting - you can do the one without the other. And the examples mixing static and dynamic languages are silly - interfaces are there in c# because the language requires them - but hey, here’s DI in Erlang / elixir https://github.com/jechol/definject . You can do the injection by passing the value.

    But a more formalised injection with a standard container makes sense once the project grows because:

    • you don’t want to start the app with 10+ type parameters for injection deeper in the call stack
    • 3rd party libraries may use the same container making integration easier
    • when you add email notification to an existing large app - you really don’t want to pass the mailer and email setting classes to dozens of other classes throughout the code
    • when using a special test constructor, you may end up with convoluted logic (how do you add “fails on the 3rd call” to your normal function?)
    • the c# framework shown is actually pretty good with GC because you can configure types to be reused per-scope, or static - making things like “give me the db connection (for this request)” exactly the same in usage as “give me a logger (static global)”

    So go ahead, use explicit passing of objects in simple apps - sometimes it is easier. MS with the DI + hosting extensions is not saying you have to do it their way. It’s more: we’re not new to this, at larger scale you’ll want to implement these features anyway, so use our common set if you want to save yourself some boilerplate.

    1. 3

      I think that this is crucially related to the SHEARING LAYERS pattern from the “Big Ball of Mud” paper. (You must read the entire paper, but the section stands alone too.) Dependency injection is not just about inverting control and using higher-order functions, but about stratifying the functionality of monolithic applications so that maintenance is cheaper.

      1. 3

        I think the best way to understand DI is: historically.

        DI never occurred to people using C++ or Smalltalk, or even early Java. It only surfaced with the advent of Enterprise Java Beans (EJB) as a way to allow 1) separation between business logic and framework code in a “container” and, 2) testability independent of the framework. It was a way to facilitate the creation of POJOs (plain old Java classes) in the middle of framework hell.

        It still can be useful, but it can be overused. I tend to favor just adding special purpose constructors for testing in an OO context if there isn’t already a DI framework in place.

        1. 4

          DI never occurred to people using C++ or Smalltalk, or even early Java.

          oh, I really disagree. I’ve taught C++ classes in uni and saw students come up with the concept pretty much on their own.

          1. 2

            Agreed, many (most?) applications not using DI as an intentional “pattern” are going to implement some subset of it just to maintain separation of concerns. Using Spring is just acknowledging this upfront, knowing that you’ll have all the tools you need to let your modules consume each other.

            1. 1

              Prior to EJB?

              1. 1

                The students I’m talking about had been exposed to programming overall for less than two years, and certainly not to enterprise java beans, only C, LISP, a hint of C++ and raw Java, and algorithms