1
votes

I am feeling stuck in my MPA ABP app development between three principles that I believe are DDD ones :

  • Application service has not to be tied to a controller. I mean a controller doesn't have to use always only one application service. Because application service conception has not presentation in mind.
  • DTO has to fit the view needs to minimize HTTP data transfer. So sometimes we have to design one DTO class per entity/concept and per view.
  • Application services get and return always DTO's.

Now I have a view which follows the Master-Detail principle: select one entity in the Master part from an entity list loads entity details in the Details part by Ajax call. But the entity selection in Master part is made by Ajax-synchronized cascade of dropdown lists: ParentEntities > Entities.

What choice respects better DDD ?

  1. Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService, then my application service can return optimized DTO's for my view needs, but violates DDD principle,
  2. Put each of theses three methods in different application services, isolated more "domain" in mind, but DTO's are domain-oriented, somewhat generic. So DTO's are not optimized.
  3. Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.
2

2 Answers

1
votes
  • Application service has not to be tied to a controller. I mean a controller doesn't have to use always only one application service. Because application service conception has not presentation in mind.

Application services are not tied to the client type, but to the client needings. They return the data that client needs, so in that sense application services has the client (presentation) in mind.

  • Application services get and return always DTO's.

Not always. There are alternatives to DTOs, as Vaughn Vernon says in his book Implementing DDD (page 512):

  • Mediator

  • Domain Payload Object

  • State Representations

  • Use Case optimal repository queries (closed to CQRS)

  • Data Transformers

What choice respects better DDD ?

  1. Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService, then my application service can return optimized DTO's for my view needs, but violates DDD principle,

You shouldn't name the application service refering the client technology (MyView), but according to the functionality it offers.

  1. Put each of theses three methods in different application services, isolated more "domain" in mind, but DTO's are domain-oriented, somewhat generic. So DTO's are not optimized.

It doesn't matter if you put the 3 methods in just one service or you have one service for each method. The controller should call them anyway.

  1. Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.

If you mean the application service returns domain objects and the controller translates them to DTOs, then no, you shouldn't do that as you are exposing the domain to clients.

0
votes

I understand your problem I think, let's start at the beginning:

...Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService...

Which of those words would a business person understand? Are any of those words part of the ubiquitous language?

They are of course all purely technical, therefore should be detail and should not influence the architecture. Basically they would be in the wrong place, they should not be visible at all.

...but DTO's are domain-oriented, somewhat generic. So DTO's are not optimized...

DTOs should not be part of anything remotely object-oriented. However, you did not say you want object-orientation so let's not dwell on that.

Still, if your object is supposed to be domain-oriented, then how come it's unfit (not optimized) for the application that is written specifically for that domain?

I think the problem is that your "object" is actually modeling something different than the domain. It's likely modeling the database table or its records.

I mean, if you are showing a profile for a product, then your "object" should be ProductProfile, not the generic Product. Or ProductDetails, or ProductHeroImage, and so on. Those things are of the domain and likely mentioned in the requirements document too.

Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.

Why should it not do that? If the purpose of your feature is to show some data to the user, then why is that not considered a "business function". I mean it should be literally the other way around. The "view" is the business function you want, and the database/repository/controller/service or whatever is "just" technology that should be just a detail and not visible in the architecture.

Disclaimer: I must admit these views are not what most projects do under DDD, but maybe you find some sense in it to question those projects more in the future.:)