I think that anyone can agree that good code is S.O.L.I.D. code, and Dependency Inversion Principle (DIP) is a very important one.
The principle states that:
A. High-level modules should not depend on low-level modules. Both should depend
B. Abstractions should not depend upon details. Details should depend upon
DIP is very useful when you want to isolate a more abstract type from it’s dependencies (details) by usage of interfaces which receive a concrete type via Dependency Injection pattern. So instead of having a direct dependency like this…
…you put an interface between the two components like this:
Noting too special until now but what about the physical location of the interface?
Consider that HighLevelComponent is part of the domain layer and needs to use a service that is part of the infrastructure layer. Usually you want to keep components/layers into their own assemblies so it’s obvious that HighLevelComponent and his concrete dependency must be in separate assemblies but what about the interface? Where do you put it?
One option and I think the most widely used solution is when the interface of the service is in the same layer as the service concrete type like in the image bellow.
This can be a viable option sometimes but it has the disadvantage that it maintains a direct dependency from the Domain layer/assembly to the infrastructure layer/assembly. So at class level the dependencies are inverted but at a higher level, that is the assembly level, they are not. This means that changes in interface to the lower level services can affect more easily their users from the layer on top.
A more appropriate solution would be to include the service interface in the same assembly with its users (see image bellow). In his book, Agile Principles, Patterns and Practices in C#, Robert C. Martin calls this “ownership inversion”. This way the dependencies are inverted at assembly level also and the interface of the service will only need to change when its user(s) require it.