Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AutoMapper to unflatten a DTO

I've been trying to use AutoMapper to save some time going from my DTOs to my domain objects, but I'm having trouble configuring the map so that it works, and I'm beginning to wonder if AutoMapper might be the wrong tool for the job.

Consider this example of domain objects (one entity and one value):

public class Person {     public string Name { get; set; }     public StreetAddress Address { get; set; } }  public class StreetAddress {     public string Address { get; set; }     public string City { get; set; }     public string State { get; set; } } 

My DTO (from a Linq-to-SQL object) is coming out looking roughly like this:

public class PersonDTO {     public string Name { get; set; }     public string Address { get; set; }     public string City { get; set; }     public string State { get; set; } } 

I'd like to be able to do this in my repository:

return Mapper.Map<PersonDTO, Person>(result); 

I've tried configuring AutoMapper every way I can figure, but I keep getting the generic Missing type map configuration or unsupported mapping error, with no details to tell me where I'm failing.

I've tried a number of different configurations, but here are a few:

Mapper.CreateMap<PersonDTO, Person>()     .ForMember(dest => dest.Address, opt => opt.MapFrom(Mapper.Map<Person, Domain.StreetAddress>)); 

and

Mapper.CreateMap<Person, Domain.Person>()     .ForMember(dest => dest.Address.Address1, opt => opt.MapFrom(src => src.Address))     .ForMember(dest => dest.Address.City, opt => opt.MapFrom(src => src.City))     .ForMember(dest => dest.Address.State, opt => opt.MapFrom(src => src.State)); 

I've read that flattening objects with AutoMapper is easy, but unflattening them isn't easy...or even possible. Can anyone tell me whether I'm trying to do the impossible, and if not what I'm doing wrong?

Note that my actual objects are a little more complicated, so it's possible I'm leaving out info that is the key to the error...if what I'm doing looks right I can provide more info or start simplifying my objects for testing.

like image 337
Josh Anderson Avatar asked Jun 29 '10 21:06

Josh Anderson


People also ask

When should you not use AutoMapper?

If you have to do complex mapping behavior, it might be better to avoid using AutoMapper for that scenario. Reverse mapping can get very complicated very quickly, and unless it's very simple, you can have business logic showing up in mapping configuration.

Does AutoMapper work both ways?

In AutoMapper you have a Source type and a Destination type. So you will be able to map between this Source type and Destination type only if you have a corresponding CreateMap. So to answer your questions: You don't need to define the reverse mapping.

How do I use AutoMapper to list a map?

How do I use AutoMapper? First, you need both a source and destination type to work with. The destination type's design can be influenced by the layer in which it lives, but AutoMapper works best as long as the names of the members match up to the source type's members.


1 Answers

This also seems to work for me:

Mapper.CreateMap<PersonDto, Address>(); Mapper.CreateMap<PersonDto, Person>()         .ForMember(dest => dest.Address, opt => opt.MapFrom( src => src ))); 

Basically, create a mapping from the dto to both objects, and then use it as the source for the child object.

like image 188
sydneyos Avatar answered Oct 04 '22 17:10

sydneyos