At work we teach and consult on various topics, notably (for this post) Angular. We are often asked why Angular has and heavily uses dependency injection. Here are my answers to this question; I haven’t had a chance to compare notes with the rest of our Angular expert team, so here it is, on my personal blog. (However, special thanks to Paul Spears, who helped clarify these ideas.)
Dependency injection has a considerable complexity cost, so it’s important to have good reasons to add this complexity to a framework or application. There are an unlimited number of potential features and patterns to follow, so the default for any particular feature or pattern must be “no”. Moreover, popular Angular alternatives (like React) thrive without a dependency injection system, constituting an “existence proof” that it is not a necessity, but rather a choice.