Dependency injection znamena 'posli mi objekt jako parametr, at si ho nemusim vytvaret sam'.
Rozlišil bych DI jako princip, který klade důraz na popisnost. Tedy
1/ objekt se veřejně hlásí ke svým závislostem
2/ nic si pokoutně nevytváří, to znamená méně nečekaných side-effektů
3/ IMHO to dost pomáhá tomu, aby se udržoval rozumný počet závislostí. Nevzdory obavám začátečníků, málokdy se stane, že by objekt měl "nepříjemně" mnoho závislostí.
4/ Hodně to pomáhá refactoringu. Vzhledem k tomu, že konstruktor obvykle není součástí žádného rozhraní, tak přidat nebo odebrat nějakou závislost je velice levné (občas to trochu komplikují testy).
Na druhou stranu tu máme DI kontainer, který je zase něco úplně jiného. Ten bejvá naopak plnej magie, ale je to velice pohodlná a návyková záležitost. A krom situace, kdy jsem potřeboval kombinovat dva kontainery dohromady jsem zatím nijak zvlášť nenarazil (zkušenosti v tomto vítány).
Taky mám zkušenost, že DIC v typovaném jazyce je subjektivně příjemnější, než v netypovaném (python, javascript).