Search code examples
c#interfaceservice-layer

Should a DTO Interface be defined in Domain or Service Layer?


I want the adpaters to pass a common interface to the cart service. I've read that interfaces should be in the Domain layer and DTOs to be defined in the Services layer, which seems to conflict with me. You don't want the Domain layer to have a reference to the Service layer where the DTO is defined.

What am I missing? Or is it ok to have the interface live with the DTO in the service layer, like I have in the diagram?

enter image description here


Solution

  • So if you use layered architecture pattern (I presume you do), one fundamental property of this pattern should be taken into consideration. This property implies specific order of "use" dependencies between the modules (classes) in different layers, in particular modules from a layer should "use" (be dependent) on modules or abstractions from the next underlying layer or layers. I mentioned layers because there can be some relaxed constraints which allow to use not only classes from the nearest underlying layer but all layers which are below the given one. As for for the upward dependencies the constraints are very strict and explicit - it's not allowed otherwise it's not a layered architecture but something else since it eliminates the quality attributes the layered architecture is supposed to bring. As a logical consequence - using DTO from the service layer inside the domain layer implies upward dependencies which violates layered architecture constraints.

    As for interfaces, another fundamental property of layered architecture is that the layers should be isolated from each other by means of abstractions. The abstractions here may imply some public contracts (API, interfaces, etc.) which define higher layers intentions and lower layers expectations but nothing more which makes layered architecture so attractive from the modifiability and portability perspective. That's why we are talking about interfaces in all layers which are just an abstraction mechanism.

    Now as a conclusion: if your DTOs are in the service layer they should be part of the contracts of the same layer (or layers above in some cases) but not below in order to exclude upward dependencies between the layers. The interfaces are still valid (and even desirable) for the domain layer as well as for any other layer for the abstraction purposes.