jasontaylordev / CleanArchitecture

Clean Architecture Solution Template for ASP.NET Core
MIT License
16.58k stars 3.56k forks source link

Mapping from VMs and DTOs to Domain Models #7

Closed JudeVajira closed 4 years ago

JudeVajira commented 4 years ago

I understand mapping from Domain Models to DTOs/Vms can be done using IMapFrom<>, but in case of updating a domain entity we will not be able to use IMapFrom<> as that would mean Domain layer would need to reference the Application layer and that is not recommended.

So as far as I see for now the 2 options available are to either,

1) Write the code by hand where you take the data from DTOs/Vms and update the Domain entities. 2) Have separate AutoMapper profiles in the Application layer to map the DTOs/Vms to the Domain models.

If we go with the 2nd option then the mapping configurations would be in DTOs and also in other mapping configuration files which feels a bit weird. Or do you recommend always going with option 1 no matter how many fields a DTO/Vm has (can get messy if handling lists and complex objects).

What would be the better practice or an alternative solution to solve this?

ghost commented 4 years ago

I was actually about the ask the exactly same question. What would be the ideal way to handle this? For example a command that creates a complex work item object that would then get saved to the db. You 'could' map it all by hand in the *CommandHandler.Handle but that does seem like a lot of work when you could have something like AutoMapper do a reverse map on it for you... Really curious how well this ideal will scale with lots of different types of complex domain entities.

mnsrulz commented 4 years ago

Did you guys able to figure out the way? I am on the same boat too

GFoley83 commented 4 years ago

All mapping should be taking place in the Application layer, in both directions. Your request command/query should contain enough information to be able to map from a DTO to a Domain entity and vice versa, with the configuration taking place inside the DTO by having it inherit from
IMapFrom<SomeDomainEntity>.

E.g. https://github.com/jasontaylordev/CleanArchitecture/blob/master/src/Application/TodoLists/Queries/GetTodos/TodoItemDto.cs#L21

Then in your Handler you can have var todoListDto = _mapper.Map<TodoList, TodoListDto>(todoList); and vice versa. Or use the the ProjectTo logic to only select the properties you need, direct from the database, for more straightforward mapping tasks.

No need to do any manual mapping.

jasontaylordev commented 4 years ago

Hi All. Sorry for taking so long to respond, I am working on getting caught up now.

I discourage auto-mapping from DTO to Domain entity. It is better to do this by hand. This way you have complete control in regard to exactly what is changing within the domain. This is even more important when following a DDD approach that controls access to properties.

Happy Coding! 😀

JudeVajira commented 4 years ago

Oh ok. Thanks for your input! Thought having something like MapTo would be ok. But I understand your point and it does make sense.

On Wed, 25 Mar 2020, 4:39 pm Jason Taylor, notifications@github.com wrote:

Hi All. Sorry for taking so long to respond, I am working on getting caught up now.

I discourage auto-mapping from DTO to Domain entity. It is better to do this by hand. This way you have complete control in regard to exactly what is changing within the domain. This is even more important when following a DDD approach that controls access to properties.

Happy Coding! 😀

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jasontaylordev/CleanArchitecture/issues/7#issuecomment-603780483, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEHAQFVUYWRNREDDT4EOMULRJHQ77ANCNFSM4JS55KDA .