Mapping one source class to multiple derived classes with automapper

后端 未结 3 1380
忘掉有多难
忘掉有多难 2021-02-03 22:46

Suppose i have a source class:

public class Source
{
    //Several properties that can be mapped to DerivedBase and its subclasses
}

And some d

3条回答
  •  孤街浪徒
    2021-02-03 23:42

    Include derived mappings into base mapping:

    Mapper.CreateMap()
        .ForMember(d => d.Id, op => op.MapFrom(s => s.Id)) // you can remove this
        .Include()
        .Include();
    
    Mapper.CreateMap()
        .ForMember(d => d.Name, op => op.MapFrom(s => s.Text))
        .ForMember(d => d.Value2, op => op.MapFrom(s => s.Amount));
    
    Mapper.CreateMap()
        .ForMember(d => d.Value, op => op.MapFrom(s => s.Amount));
    

    Usage:

    Mapper.AssertConfigurationIsValid();
    var s = new Source() { Id = 2, Amount = 10M, Text = "foo" };
    var d1 = Mapper.Map(s);
    var d2 = Mapper.Map(s);
    

    See Mapping inheritance on AutoMapper wiki.


    UPDATE: Here is full code of classes which works as it should.

    public class Source
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public decimal Amount { get; set; }
    }
    
    public class DestinationBase
    {
        public int Id { get; set; }
    }
    
    public class DestinationDerived1 : DestinationBase
    {
        public string Name { get; set; }
        public decimal Value2 { get; set; }
    }
    
    public class DestinationDerived2 : DestinationBase
    {
        public decimal Value { get; set; }
    }
    

    UPDATE (workaround of AutoMapper bug):

    public static class Extensions
    {
        public static IMappingExpression MapBase(
            this IMappingExpression mapping)
            where TDestination: DestinationBase
        {
            // all base class mappings goes here
            return mapping.ForMember(d => d.Test3, e => e.MapFrom(s => s.Test));
        }
    }
    

    And all mappings:

        Mapper.CreateMap()
              .Include()
              .Include()
              .MapBase();
    
        Mapper.CreateMap()
              .MapBase()
              .ForMember(d => d.Test4, e => e.MapFrom(s => s.Test2));
    
        Mapper.CreateMap()
              .MapBase()
              .ForMember(d => d.Test5, e => e.MapFrom(s => s.Test2));
    

提交回复
热议问题