The first reference to what would eventually become Dependency Injection appeared in 1994 in a paper by Robert C. Martin called "The Dependency Inversion Principle".
In "The Dependency Inversion Principle" (or DIP), the author states the three defining factors of "bad code":
- It is hard to change because every change affects too many other parts of the system (Rigidity)
- When you make a change, unexpected parts of the system break (Fragility)
- It is hard to reuse in another application because it cannot be disentangled from the current application (Immobility)
According to Martin, interdependency causes these coding problems (we'll call them RFI for Rigidity, Fragility, and Immobility). To fix RFI issues in your OO code, DIP has two basic rules:
1. High level modules should not depend upon low level modules, both should depend upon abstractions.
In other words, high level modules – which contain your business logic and all of the important meat of your application – should not depend on lower level components. The reason for this is if these lower level components were to change, the changes might affect the higher level components as well. This is the defining concept behind dependency inversion, that the prevailing wisdom of having higher-level modules dependent on lower-level modules is in fact a bad idea.
2. Abstractions should not depend upon details, details should depend upon abstractions.
This is another way to say that before you begin coding to the abstraction – the interface or abstract class – you should find the common behaviors in the code and work backwards. Your interface abstraction should cater to the intersection between the needs of your business logic and the common behaviors of the lower level modules. You should also leave the details of how these behaviors are implemented to the implementation classes.