Los Techies : Blogs about software and anything tech!

The case for two-way mapping in AutoMapper


I’m getting more and more requests around the area of two-way mapping, meaning you’d do something like:

Product –> ProductDTO

ProductDTO –> Product

Product being an entity, I can’t for the life of me understand why I’d want to dump a DTO straight back in to a model object.  To get some understanding of how we use AutoMapper, we have:

  • 1500 individual mapping definitions
  • 75 custom value resolvers
  • 38 custom value formatters
  • 5 individual profiles

So what are we using AutoMapper for?  Our five profiles include:

  • From Domain to ViewModel (strongly-typed view models for MVC)
  • From Domain to EditModel (strongly-typed view models for forms in MVC)
  • 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.
  • From Domain to ReportModel – strongly-typed Telerik reports
  • From Domain to EDI Model – flattened models used to generate EDI reports

There is no two-way mapping because we never need two-way mapping.  There was a point very early on where we were at a critical junction, and could decide to do two-way mapping.  But we didn’t.  Why?  Because then our mapping layer would influence our domain model.  I strongly believe in POCOs, and a very writeable domain model meant that POCOs were out.  What exactly would two-way mapping do to our domain layer?

  • Force mutable, public collection , like “public EntitySet<Category> Categories { get; }” <- NO.
  • Make testing much, much harder, as we only ever wanted to update a portion of a domain model
  • Force our domain model to be mutable everywhere

So my question to those wanting two-way mapping:

  • What scenarios are you looking at doing two-way mapping?
  • What impact would two-way mapping have on the originating source type?
  • How would you test two-way mappings?

I think using AutoMapper because you don’t want to use the “=” operator is a bit lazy.  Instead, we use it to flatten and reshape, optimizing for the destination type’s environment.  Remember, my original motivation for AutoMapper was:

  • Enable protecting the domain layer from other layers by mapping to DTOs
  • Enable easy testing of the mappings, which would otherwise prevent us from creating the mapping in the first place

So…why two-way mapping?

Kick It on DotNetKicks.com
Posted Sep 17 2009, 09:33 PM by bogardj
Filed under:

Comments

Gagan Rajpal wrote re: The case for two-way mapping in AutoMapper
on 09-17-2009 11:27 PM

One scenario where a two way mapping could be useful would be domain model to dto which gets passed through a web service and then dto to domain model. you may not necessarily want to pass the domain model thru the web service to reduce overhead, or due to serialization issues.

Gagan

Gagan Rajpal wrote re: The case for two-way mapping in AutoMapper
on 09-17-2009 11:30 PM

to be more specific, its not necessarily a two way mapping, but rather a

source domain model to dto, this dto is exposed thru a web  service then dto to target domain model,,,, the source and target domain model need not necessarily be exactly the same.

Vijay Santhanam wrote re: The case for two-way mapping in AutoMapper
on 09-18-2009 12:08 AM

I don't particularly mind two way mapping being separate, but with MS MVC I do have alot of EditModels that are converted from DomainModels (for edit forms) and back again (when save is pressed).

Reflective Perspective - Chris Alcock » The Morning Brew #436 wrote Reflective Perspective - Chris Alcock &raquo; The Morning Brew #436
on 09-18-2009 3:36 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #436

Igor Brejc wrote re: The case for two-way mapping in AutoMapper
on 09-18-2009 8:49 AM

We have an "external" domain model generated from Web service data contract, but it doesn't fit our needs internally (for MVC), so we implemented our own. But we still need two-way mapping between those two models (for Web service's input and output parameters)

Jeff Lembke wrote re: The case for two-way mapping in AutoMapper
on 09-18-2009 1:56 PM

Thanks for this. We'd wanted to do mapping to Domain objects and created the very tension you are talking about. This helped clear up my thinking.

Paul Blamire wrote re: The case for two-way mapping in AutoMapper
on 09-18-2009 4:46 PM

Hi Jimmy,

Have you blogged about how you convert the EditModel to CommandMessages before? I don't remember that, and a search for CommandMessages doesn't return anything.

I'd be very interested to learn a little more about some of the specifics, just to see how the alpha devs route information back from form to model (not viewmodel). Obviously I initially just thought you were creating the message to pass into the service layer to perform the form operation, the fact you said you may produce many commands though made me wonder if there was more to it?  

I suspect this is where you neatly sidestep any perceived requirement for 2 way mapping.

Loving all the automapper posts, great work :-)

Mikael Henriksson wrote re: The case for two-way mapping in AutoMapper
on 09-19-2009 8:04 AM

I use Automapper one way only. Mostly used it when I am too lazy and need to copy one entity to another entity straight off but it would be extremely usefull for ASP.NET MVC as well. Never had any use for any two way copying.

Klenne wrote re: The case for two-way mapping in AutoMapper
on 09-21-2009 11:06 AM

We have a domain model that we map to DTO objects requested by the client application.  At the client layer these DTO objects are used to display/edit info.  When such a DTO is received at our backend service, we map it to a domain model again.  Sometimes straightforward mapping is not possible, sometimes it is.  That's when 2 way mapping comes into play.  How are you mapping incoming DTO to your domain model?

bogardj wrote re: The case for two-way mapping in AutoMapper
on 09-22-2009 6:49 PM

@Klenne

Incoming DTOs are mapped to command messages, which are handled individually.  Sometimes this results in modifying the domain, sometimes not.  It's not always the same, and it's never as simple as going from domain -> DTO, which is why we ditched trying.

Jan Ove Skogheim Olsen wrote re: The case for two-way mapping in AutoMapper
on 09-24-2009 4:27 AM

The need for two-way mapping comes from people doing basic data driven CRUD operations through their service layers. So instead of fixing the real problem of not doing so, they want AutoMapper to save them from the trouble of having to do the mapping manually. The fact that AutoMapper don't support this is a good thing, as it enforces a good design principle of not exposing CRUD. Those who still desperately want to do it, can already do so by just setting up the mapping each way separately anyway.

Paul Sanchez wrote re: The case for two-way mapping in AutoMapper
on 09-24-2009 3:47 PM

I believe Olsen is pretty accurate. People are designing their domain to be directly mapped to and from the presentation layer. I used to do that until I started looking into command messages and realized that this is the better way to go. Even if I did want to map to and from a presentation model, the mapping logic would be different in each direction.

I wouldn't even know how the AutoMapper API should be written to handle such a scenario. Before hitting this thread, I just set up the mapping each way separately.

Part of the documentation of AutoMapper should probably state the design patterns it is expected to be used within.

Pat Gannon wrote re: The case for two-way mapping in AutoMapper
on 09-24-2009 8:42 PM

2-way mapping would be very handy for us here at HSI.  We have AutoMapper.CreateMap<AEntity,AContract> and then AutoMapper.CreateMap<AContract,AEntity> all over the place.

To answer your questions...

   *  What scenarios are you looking at doing two-way mapping?

Mapping DTOs to entities and then entities back to DTOs.  For one example, we have a workflow application that gets data from a web service (which comes from a DB by way of entities and NH).  The user can then make changes in the app, publish the contracts back to the web service (which puts them back in the DB by way of entities and NH).

   * What impact would two-way mapping have on the originating source type?

None.  For simple entities where the only sensible DTO shape looks exactly like the entity, 2-way mapping would be very handy.  (This is common.)  For more complex entities where the DTO would make more sense having a different shape than the entity, then you could have separate mappings for DTO -> Entity and Entity -> DTO to re-shape the data according to your needs.

   * How would you test two-way mappings?

Test the translation of a DTO to entity and then separately test the translation of an entity to a DTO (or what have you).

Hoghweed wrote re: The case for two-way mapping in AutoMapper
on 10-05-2009 1:12 PM

I'm interested in a practical example of what you mean about "not needing a two way binding".

This because if I think about mapping a Model POCO to a ViewModel then after MVC model binding, I want to remap some part of my ViewModel to a Model Object just because I use it as an input of our service methods, and I'm courios about how you have implemented what you said

ASP.NET MVC Archived Buzz, Page 1 wrote ASP.NET MVC Archived Buzz, Page 1
on 12-28-2009 1:00 PM

Pingback from  ASP.NET MVC Archived Buzz, Page 1

Alex G. wrote re: The case for two-way mapping in AutoMapper
on 12-28-2009 7:10 PM

Can someone explain further the concept of command messages and include a sample using automapper?  It might be helpful for those of us who do not understand the concepts behind it and why it might be useful over a DTO->entity mapping.

Piers wrote re: The case for two-way mapping in AutoMapper
on 01-19-2010 7:49 PM

I'd like to put forward an argument for 2 way mapping... that might just illustrate my lack of ability to see the wood for the trees, but here goes:

Olsen, above, was indicating that performing CRUD throughout an application stack was a bad smell, but looking at REST based services, that can be what 80% of the functionality needs to do. However, its not straight CRUD... for instance, if a client does a GET on a resource, the representation they recieve probably won't be a straight serialisation of an entity object. You'll probably want to add some data (e.g. the resource's URI and URIs of related resources). YOu might want to hide some data (e.g. confidential data like total number of sales of a product). These all seem good reasons to have a DTO and to introduce AutoMapper.

But what about when the client PUT or POSTs the representation back... it will be in the same form that the DTO was served to them. So probably the simplest type to deserialise that representation into is the DTO that was used for the GET processing. What next in this "CRUD" process?

Without two way mapping it appears I have two choices:

1) Hand crank the code to retrieve the entity from the database and change some of its values to match those passed in by the client, the save. This seems a shame since I'm only doing the reverse of what AutoMapper did automatically for me (i.e. AutoMapper has been fantastic for half of my functionality). This could work for a simple service, but as the service has to support more representations of the same entity, the amount of code would really build up.

2) As suggested by other commentors, have two separate mappings Entity -> DTO and DTO -> Entity... but, hang on, the DTO -> Entity mapping won't pass validation because the DTO doesn't have enough properties to populate the entire Entity. Remember, the confidential data mentioned above is not available in the DTO.

Neither of these is satisfactory. My ideal would be a single Entity -> DTO mapping that was capable of merging a DTO back into an existing Entity (i.e. it only updated the fields in the Entity that the mapping was populating in the opposite direction).

So does this count as a viable reason? Or am I missing an obvious alternative?

bogardj wrote re: The case for two-way mapping in AutoMapper
on 01-20-2010 8:55 AM

@Piers

One thing to look at is to see how other MVC frameworks solve this problem.  For example, do Rails folks use DTOs?  If not, what is built into Rails that solves the screen/entity divide?

For me personally, if I didn't _have_ to use AutoMapper, I wouldn't.  If a screen is editing an entity, and I could somehow make model binding work that it wouldn't screw everything up, I would.  Otherwise, it's an extra layer that I might not need.

I'm going to chat with some Rails folks and see what they're doing, and maybe that will answer the larger question.

Nick Y wrote re: The case for two-way mapping in AutoMapper
on 01-20-2010 10:58 AM

Jimmy, I'd like to explore the Command Message route, but I haven't been able to find any blogs/articles about it.

The CodeCampServer and Tarantino RulesEngine are all I've been able to find - is this the best place to learn about the pattern? Any other guidance would be much appreciated.

Chris Nicola wrote re: The case for two-way mapping in AutoMapper
on 02-02-2010 4:04 PM

Another benefit to using a CommandMessage is the ability to handle them asynchronously or treat them as events using an EventAggregator to allow different services to subscribe to them.

Jonathan Tew wrote re: The case for two-way mapping in AutoMapper
on 02-11-2010 7:01 PM

Thanks, good article. I'd been wondering why there wasn't any consideration for 2-way in AutoMapper but it makes sense now.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:
Copyright Los Techies 2008, 2009. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems