Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper and inheritance - How to Map?

Have this scenario:

public class Base {  public string Name; }  public Class ClassA :Base {  public int32 Number;  }  public Class ClassB :Base { public string Description;}  public Class DTO {   public string Name;   public int32 Number;   public string Description; } 

I have an IList<Base> my maps are:

AutoMapper.Mapper.CreateMap<IList<Base>, IList<DTO>>()    .ForMember(dest => dest.Number, opt => opt.Ignore())    .ForMember(dest => dest.Description, opt => opt.Ignore());  AutoMapper.Mapper.CreateMap<ClassA, DTo>()    .ForMember(dest => dest.Description, opt => opt.Ignore());  AutoMapper.Mapper.CreateMap<ClassB, DTO>()    .ForMember(dest => dest.Number, opt => opt.Ignore())  Mapper.AssertConfigurationIsValid(); //Is OK! 

But Properties that are in ClassA Or ClassB are not mapped when I do this :

IList<DTO>= AutoMapper.Mapper.Map<IList<Base>,IList<DTO>>(baseList); 

How can I do to map properties that are defined in ClasA and ClassB

like image 368
Gringo Avatar asked Jul 27 '10 22:07

Gringo


People also ask

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.

Does AutoMapper map both ways?

Yes, or you can call CreateMap<ModelClass, ViewModelClass>(). ReverseMap() .

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.


1 Answers

You will need to create DTO classes that match your domain classes like this:

public class DTO {     public string Name; }  public class DTO_A : DTO {     public int Number { get; set; } }  public class DTO_B : DTO {     public string Description { get; set; } } 

You then need to change your mappings to this:

        Mapper.CreateMap<Base, DTO>()             .Include<ClassA, DTO_A>()             .Include<ClassB, DTO_B>();          Mapper.CreateMap<ClassA, DTO_A>();          Mapper.CreateMap<ClassB, DTO_B>();          Mapper.AssertConfigurationIsValid(); 

Once this is done, then the following will work:

        var baseList = new List<Base>         {             new Base {Name = "Base"},             new ClassA {Name = "ClassA", Number = 1},             new ClassB {Name = "ClassB", Description = "Desc"},         };          var test = Mapper.Map<IList<Base>,IList<DTO>>(baseList);         Console.WriteLine(test[0].Name);         Console.WriteLine(test[1].Name);         Console.WriteLine(((DTO_A)test[1]).Number);         Console.WriteLine(test[2].Name);         Console.WriteLine(((DTO_B)test[2]).Description);         Console.ReadLine(); 

Unfortunately this does mean that you have an unwanted cast, but I don't think there's much that you can do about that.

like image 179
Simon Avatar answered Oct 09 '22 13:10

Simon