A really simple rule of thumb is that you should only use a DTO object when you need to ... transfer data. That means use a DTO at the boundaries inof your web API, or when you are sending the object on a message bus. Internally, just use your domain objects.
The only reason a DTO should exist is the limitations of the (de)serialization layers. Those need simple objects without complex logic.
RecommendationRecommendations:
- Use standard models in your servicesservices;
- Convert the model to a DTO in the controller (i.e. in your web application) just prior to serialization.serialization;
- If you use asynchronous messaging, convert the model to a DTO just before pushing the DTO on the message queue.
This allows you to use your services as you desire, and save the DTOs for when they are actually required.