Dependency inversion principle : High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions.
Advantage:
a. You do not have to develop the lower level modules before developing the higher level modules. Thus a top-down approach is possible in both design and development.
b. Objects in the lower layers are injected into the higher level objects. The result is that components are less tightly coupled, and there is a high degree of separation of concerns.
c. The individual components are more easily testable and the higher level objects can be tested with mock objects in place of lower level services.
Separation of Conserns (SOC) is the motive of creation of DI(IOC) and AOP.
Using DI, we decouple two modules. But actually, we haven't eliminated the connections between two modules, instead we just move the connection to another place.
The transfer of this connection is a type of SOC, and it provide the possibility of AOP.
DI:
The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface.
There are three main styles of dependency injection, they are Constructor Injection, Setter Injection, and Interface Injection.