In an ASP.NET MVC project we are using AutoMapper to map from domain model to viewmodel - and sometimes also flattening a hierarchy while doing so. This works like a charm and makes the rendering logic of our views very lean and simple.
The confusion starts when we want to go the other way from viewmodel (or postmodel or editmodel) to domain model, especially when updating objects. We can't use automated/two-way mapping because:
- we would have to unflat the flattened hierarchy
- all properties on the domain model would have to be mutable/have public setters
- the changes coming from the view isn't always just flat properties being mapped back to the domain, but sometimes need to call methods like "
ChangeManagerForEmployee()
" or similar.
This is also described in Jimmy Bogards article: The case for two-way mapping in AutoMapper, but the solution to this isn't described in detail, only that they go:
From EditModel to CommandMessages – going from the loosely-typed EditModel to strongly-typed, broken out messages. A single EditModel might generate a half-dozen messages.
In a similar SO question there is an answer by Mark Seeman where he mentions that
We use abstract mappers and services to map a PostModel to a Domain Object
but the details - the conceptual and technical implementation - is left out.
Our idea right now is to:
- Recieve a FormCollection in the controller's action method
- Get the original domain model and flatten it to viewModelOriginal and viewModelUpdated
- Merging the FormCollection into viewModelUpdated using
UpdateModel()
- Use some generic helper method to compare viewModelOriginal with viewModelUpdated
- Either A) Generate CommandMessages a la Jimmy Bogard or B) Mutate the differences directly into the domain model through properties and methods (maybe mapping the 1-1 properties directly through AutoMapper)
Can someone provide some examples of how they come from FormCollection through editmodel/postmodel to domain model? "CommandMessages" or "abstract mappers and services"?
I use the following pattern: