Search code examples
c#automapperautomapper-6

Automapper - map abstract to abstract


Source classes:

public abstract class ApplicationDriverEquipmentFormAbstractVM
{
    [StringLength(256)]
    public string Make { get; set; }
    [StringLength(256)]
    public string Model { get; set; }
    [StringLength(256)]
    public string Year { get; set; }
    [StringLength(256)]
    public string PlateNumber { get; set; }
    [StringLength(256)]
    public string CurrentMileage { get; set; }
}

public class ApplicationDriverEquipmentTractorFormVM : ApplicationDriverEquipmentFormAbstractVM
{
    [StringLength(256)]
    public string VINNumber { get; set; }
}

public class ApplicationDriverEquipmentTrailerFormVM : ApplicationDriverEquipmentFormAbstractVM
{
    [StringLength(256)]
    public string Length { get; set; }
}

public class ApplicationDriverEquipmentStraightTruckFormVM : ApplicationDriverEquipmentFormAbstractVM
{
    [StringLength(256)]
    public string VINNumber { get; set; }
    [StringLength(256)]
    public string Length { get; set; }
}

public class ApplicationDriverEquipmentCargoVanFormVM : ApplicationDriverEquipmentFormAbstractVM
{
    [StringLength(256)]
    public string VINNumber { get; set; }
    [StringLength(256)]
    public string Length { get; set; }
}


public class ApplicationDriverFormVM
{
    public ApplicationDriverEquipmentTractorFormVM EquipmentTractor { get; set; }
    public ApplicationDriverEquipmentTrailerFormVM EquipmentTrailer { get; set; }
    public ApplicationDriverEquipmentStraightTruckFormVM EquipmentStraightTruck { get; set; }
    public ApplicationDriverEquipmentCargoVanFormVM EquipmentCargoVan { get; set; }

}

then I want to map it to the Equipments property in destination class, which described the following way:

public class ApplicationDriverDomain
{
    public List<ApplicationDriverEquipmentAbstractDomain> Equipments { get; set; }
}

public abstract class ApplicationDriverEquipmentAbstractDomain
{
    public int Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public string PlateNumber { get; set; }
    public string CurrentMileage { get; set; }
    public string Type { get; protected set; }
}

public class ApplicationDriverEquipmentTractorDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentTractorDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor;
    }
    public string VINNumber { get; set; }
}

public class ApplicationDriverEquipmentTrailerDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentTrailerDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.Trailer;
    }

    public string Length { get; set; }
}

public class ApplicationDriverEquipmentStraightTruckDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentStraightTruckDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.StraightTruck;
    }

    public string VINNumber { get; set; }
    public string Length { get; set; }
}

public class ApplicationDriverEquipmentCargoVanDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentCargoVanDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.CargoVan;
    }

    public string VINNumber { get; set; }
    public string Length { get; set; }
}

I have wrote the following automapper rules:

        CreateMap<ViewModels.ApplicationDriverEquipmentFormAbstractVM, ApplicationDriverEquipmentAbstractDomain>();

        CreateMap<ViewModels.ApplicationDriverEquipmentTractorFormVM, ApplicationDriverEquipmentTractorDomain>();
        CreateMap<ViewModels.ApplicationDriverEquipmentTrailerFormVM, ApplicationDriverEquipmentTrailerDomain>();
        CreateMap<ViewModels.ApplicationDriverEquipmentStraightTruckFormVM, ApplicationDriverEquipmentStraightTruckDomain>();
        CreateMap<ViewModels.ApplicationDriverEquipmentCargoVanFormVM, ApplicationDriverEquipmentCargoVanDomain>();

        CreateMap<ViewModels.ApplicationDriverFormVM, ApplicationDriverDomain>()
            .ForMember(dest => dest.Equipments, opt => opt.MapFrom(src => new List<ViewModels.ApplicationDriverEquipmentFormAbstractVM>() { src.EquipmentCargoVan, src.EquipmentStraightTruck, src.EquipmentTractor, src.EquipmentTrailer }));

but it does not work. Why?


Solution

  • I found the solution. Need to declare mapping inheritance:

    CreateMap<ViewModels.ApplicationDriverEquipmentFormAbstractVM, ApplicationDriverEquipmentAbstractDomain>()
        .Include<ViewModels.ApplicationDriverEquipmentTractorFormVM, ApplicationDriverEquipmentTractorDomain>()
        .Include<ViewModels.ApplicationDriverEquipmentTrailerFormVM, ApplicationDriverEquipmentTrailerDomain>()
        .Include<ViewModels.ApplicationDriverEquipmentStraightTruckFormVM, ApplicationDriverEquipmentStraightTruckDomain>()
        .Include<ViewModels.ApplicationDriverEquipmentCargoVanFormVM, ApplicationDriverEquipmentCargoVanDomain>();
    

    Documentation about it:

    https://github.com/AutoMapper/AutoMapper/wiki/Mapping-inheritance