First, I'm an entry level programmer; In fact, I'm  finishing an A.S. degree with a final capstone project over the summer. In my new job, when there isn't some project for me to do (they're waiting to fill the team with more new hires), I've been given books to read and learn from while I wait - some textbooks, others not so much (like Code Complete). After going through these books, I've turned to the internet to learn as much as possible, and started learning about SOLID and DI (we talked some about Liskov's substitution principle, but not much else SOLID ideas). So as I've learned, I sat down to do to learn better, and began writing some code to utilize DI by hand (there are no DI frameworks on the development computers). Thing is, as I do it, I notice it feels familiar... and it seems like it is very much like work I've done in the past using composition of abstract classes using polymorphism. Am I missing a bigger picture here? Is there something about DI (at least by hand) that goes beyond that? I understand the possibility of having configurations not in code of some DI frameworks having some great benefits as far as changing things without having to recompile, but when doing it by hand, I'm not sure if it's any different than stated above... Some insight into this would be very helpful!
Is dependency injection by hand a better alternative to composition and polymorphism?
dependency injection;abstraction;polymorphism;composition
The fundamental idea in DI is simply to push dependencies into objects, rather than letting them pull dependencies from outside. This was also called inversion of control earlier. This allows one to control dependencies much better, and - last but not least - to write code which is easy to unit test.DI frameworks only build on top of this idea, and (partly) automate the often tedious part of wiring object dependencies together. This may otherwise require a significant amount of code in a larger project when done by hand.To define dependencies, apart from external configuration files, it is also possible to use code annotations nowadays, e.g. in languages like Java and C#. These may bring the best of both worlds: wiring dependencies in a declarative style, but right within the code itself, where it logically belongs to. To me, the possibility of changing dependencies without having to recompile is not that valuable, as it is rarely done in real life (apart from some special cases), but introduces an often artifical separation of dependencies from the classes and objects defined within the code.To return to your title question, DI is not an alternative to composition nor polymorphism; after all, it is made possible by these two.