How to reuse code in an application layer without mapping?
Let's have an application service OrderService with AddOrder(OrderDto) method. The method is used by rest api. A controller method calls OrderService.AddOrder(OrderDto) and it maps the OrderDto param to the Order entity. The Order entity is then added to a repository. The mapping is done there because OrderService and AddOrder is an application interface.
It would be nice to reuse the code and call OrderService.AddOrder(orderDto) not just from the controller but also from another method in OrderService or even from another application service.
However, it always needs mapping from an entity to DTO inside the application service method before calling another application method and then mapping the result back from DTO to entity.
=> Useless mapping in the same layer. With the system going bigger it ends up with mapping from and to DTO everywhere. BAD.
It would be good to avoid the mapping inside and do it only on the top of the application interface. We could write a service accepting an domain model (entity) instead of DTO in the params: OrderDomainService.AddOrder(order).
This resolves the "mapping problem". Domain services can call each other without mapping and Application services can also call the domain services. However, it means a domain service has to use a repository from Infrastructure layer to load data because we moved the code from an application service method to the domain service method. This creates a dependency from Domain layer to Infrastructure layer.
=> Wrong dependency. Infrastructure should depend on Domain, not Domain on Inrastructure.
How to resolve that?
The application service shouldn't contains methods with params of domain model types. The domain service can't use repository.
Where to write the reusable code then?
Or I'm wrong and the domain service can use the repository. Via an interface in Domain layer it wouldn't be dependent directly on the infrastructure layer. However then it would end up with a controller method calling an application service method calling an domain service method.