According to the definition by Robert Martin, high level modules should not depend on low level modules, instead both should depend on abstractions.
So if I have a domain entity Invoice
that uses an interface InvoiceRepository
for persistence, and an infrastructure layer where this interface is implemented in a class PdoInvoiceRepository
, then both modules – the entity and the persistence mechanism – depend on the abstraction (interface)?
Further, if the methods in above interface do not depend on the implementation details but instead express the abstracted needs of my domain model, then I have achieved dependency inversion?
The idea behind dependency inversion is to prevent hard-coded dependencies within a class.
If I write this:
public class Customer
{
private CustomerRepository _repository;
public Customer()
{
_repository = new CustomerRepository();
}
}
Then I have tightly bound CustomerRepository
to Customer
.
But if, instead, I write
public class Customer
{
private ICustomerRepository _repository
public Customer(ICustomerRepository repository)
{
_repository = repository;
}
}
I can then write:
var customer = new Customer(new RepositoryClassThatImplementsICustomerRepository());
So you can hand the constructor of my class any object that implements the ICustomerRepository
interface. The class is no longer tightly-coupled to a specific implementation of Customer Repository.
ICustomerRepository
is an abstraction; it defines the operations that are valid for a repository object that satisfies Customer
‘s requirements.
2