The article makes a valid point, but I think it's one that all developers should learn to recognize early on and not waste cycles bringing it up again and again. The point is: there's no silver bullet. A moderately experienced programmer should intuitively grasp that there is never one universal technique that always applies to any problem. This article seems to focus again and again on proving this point, but it doesn't need proving.

That said, while his criticisms of dependency injection have merit, he doesn't seem to recognize the myriad use cases where it actually does make sense. The one that comes to my mind most readily is database access. Say I have a Record class that wants to update a database. Among the myriad possible implementations, here are three examples that demonstrate a possible value for DI:

// Fully encapsulates behavior. Good OO, however, difficult to test;
// the function always creates a database connection
function update_naive() {
$db = new DatabaseClient($dbUser, $dbPass, $dbHost, $dbName);
$db->query("UPDATE etc");
}
// This is easier to test; the factory can be configured to return a
// mock DB connection so the method can be tested as a unit
// However, this requires boilerplate; we have to create and manage
// a factory class, and for many classes this gets cumbersome
function update_using_factory() {
$db = DBFactory::getInstance();
$db->query("UPDATE etc");
}
// A stub in the "style" of dependency injection; we've reduced
// encapsulation by having the interface declare what it does (which
// has pros and cons), but it becomes a cinch to reuse this function
// in different contexts, e.g. testing with a mock db
function update_using_di($db) {
$db->query("UPDATE etc");
}

Picture a similar scenario in the context of profiling, logging, sending signals to other services, et cetera, and the concept of using a dependency injection framework in place of creating dozens of factory classes starts to have appeal.

I can see his point regarding the overuse of dependency injection. However, I do have one point to make about injecting object dependencies vs. creating them within objects:

Let's say you are on a large multi-team project, and you are not in charge of many of the modules that you are utilizing in your classes. What happens if the footprint does change? As in a parameter is added to the constructor or something of the like? Instead of changing it in one place you have to change it in 600.

True, but I guess it's just nice knowing that the instantiation of the class is only handled in one place. I know when using Symfony2, the DI container is a very nice feature in that once you have setup and configured a service, it is very easily accessible and does not need to be constructed. Anyone else can also use this service without knowing the specific configuration details as well. I believe it is also lazy-loaded, so there is no performance hindrance if the object is not used, as the author mentioned.

But you need to look on the other side of things, if a new team member comes into the project is can be a very steep learning curve, especially debugging. DI Containers and the like provide "magic" and hide away code which can be very hard to trace, especially when there are issues.
There's always a trade off in software development, as said above there's no silver bullet.

To me, DI is less about protection from changing interfaces and more about empowering polymorphism. My class depends on the interface of another module, and dependeny injection won't make me any less vulnerable to changes in that interface. But I don't care what the implementation of that interface is. Dependency injection takes the job of instantiating the implementation away from me, so that my class only refers to the interface and not the implenting class. In a way that increases encapsulation, contrary to what the author of the article claimed.

Isn't this where the factory pattern stems from? Using the factory pattern, you have an easy way of instantiating an object in multiple ways without the parent class knowing how to call the dependent class. I believe I've heard that the factory pattern stems from DI in this way, yet another reason that DI can be a good thing in moderation. Not sure if I'm right or wrong in thinking this way?

Yeah, one thing you'll probably see if you instantiate all your dependencies from factories is that a lot of the factories look the same, and that you'll either have to write code in the factory to vary the dependencies (e.g. if the environment is test, use a mock socket resource rather than a real one), or subclass the factory.

So, in a sense, DI is just abstracting all the factories away too - you can think of the container as a single super-flexible factory.

It seems likely that the scale of change that dependency injection would hypothetically help with, would be the scale of change which would also require changes that it would not help with.

The amount of help it does provide in these situations is small, and the amount of indirection it creates is high. I agree with Marston that the tradeoff is not favorable in real-world cases I've seen.

"The heart of the argument is not should we be doing it (Dependency Injection), but how do we go about doing it."

Those statements imply that if you are not using dependency injection (DI) then you are an idiot. I take great exception to that arrogant, condescending attitude. Design patterns are an option, not a requirement. Some OO programmers attempt to go a step further by saying that not only must you use their favourite selection of design patterns, but you must also adhere to their particular method of implementation.

Pot, meet kettle.

He takes a single portion of the article and then instantly tries to demonize the author by stating that he's being arrogant and condescending. If this is arrogant and condescending then teaching anyone about anything is also arrogant and condescending. This sort of "take one or two lines out of context and flame people" style of writing is immature and counter-productive and he should be able to make all his points without it.

It is the human nature. Because some have had a little more experience they start to become arrogant and try to imply they hold the key to success; further to that attempt to implement rulings based on their own convictions... to conveniently make others build on the structure they idealize.

I agree though, there is some knowledge that can be shared from other people's experiences and is good to see their views, but never blindly follow them. Question everything.

In other words, Dependency Injection like all other ideologies has its case scenarios but IMO is far from being the goldie lock of programming.

The scale of the project obviously dictates the amount of time spent on the design pattern. In a small scale project you'd definitely run into what he calls, 'Too many Chiefs and not enough Indians'. :)

What I don't understand is all this talk about "time". I would bet that I could whip out a project as fast, if not faster, starting from a full-fledged Symfony install than starting from scratch. And I would be using DI and all the other wonderful design patterns that I could reasonably cram into it.

If your initial design incorporates the patterns, and you aren't unnecessarily using patterns "just because", then not only will you have a 'better' (more easily maintained) product in the end, but it will take hardly any more time than otherwise.

Design patterns shouldn't inherently cost more time. If used properly they should be saving time, even on small projects.

and then about 5 minutes of removing any unnecessary dependencies and the 'AcmeBundle' that the standard distribution comes with.

How much time did you invest learning how to do that?

Let me go ahead and make my point... you weren't born knowing how to implement Symfony. At some point you invested time (how much?) learning how the project works and how to implement it and customize it for your own needs.

I misunderstood. However, I'm not seeing how that has any bearing on this conversation. Your original point was that building a well-thought-out project using proper design patterns takes longer than otherwise. Yes, I have experience and so yes it might be easier for me, personally, but what does that have to do with your original point? Are you saying that the initial time investment somehow nullifies the benefits that I am arguing for? You learned how to write code in the first place. Why not learn how to make your applications more maintainable?

If we are including the initial time investment in understanding how and when to use design patterns, then yes, there is a decent chunk of time to be spent. For me, it took about 6 months spent reading this book, using Symfony, and making myself sick with google searches to really feel comfortable-- and I am still always learning new things. But that investment has proven immensely beneficial for every single project that I've worked on since.