使用派生类型从基本列表映射到另一个基本列表

Map from base list to another base list using derived types

我正在尝试映射如下内容。

public abstract class AnimalBLO { }

public abstract class AnimalDLO { }

public class HumanBLO : AnimalBLO { }

public class HumanDLO : AnimalDLO { }

public class LionBLO : AnimalBLO { }

public class LionDLO : AnimalDLO { }

internal class Program
{
    private static void Main(string[] args)
    {
        Mapper.CreateMap<HumanDLO, HumanBLO>();
        Mapper.CreateMap<LionDLO, LionBLO>();

        var dlos = new List<AnimalDLO>()
        {
            new HumanDLO(),
            new LionDLO()
        };

        var result = Mapper.Map<List<AnimalBLO>>(dlos);

    }
}

其中列表的基类型是 AnimalBLO,但它们被映射为派生类型。有没有一种方法可以做到这一点,而无需将所有对象都丢弃,然后将它们重新组合在一起?

我认为这段代码可以工作:

        Mapper.CreateMap<AnimalDLO, AnimalBLO>()
            .Include<HumanDLO, HumanBLO>()
            .Include<LionDLO, LionBLO>();

        Mapper.CreateMap<HumanDLO, HumanBLO>();
        Mapper.CreateMap<LionDLO, LionBLO>();

但是,抛出以下异常消息:

{"Instances of abstract classes cannot be created."}

A​​utoMapper 的 Mapping inheritance 功能与您描述的完全一样。我已将 Tag 属性 添加到 类 以验证调用了哪个地图:

public abstract class AnimalBLO
{
    public string Tag { get; set; }
}

这是成功的测试:

[SetUp]
public void SetUp()
{
    Mapper.Initialize(cfg => {
        cfg.CreateMap<AnimalDLO, AnimalBLO>()
              .Include<HumanDLO, HumanBLO>()
              .Include<LionDLO, LionBLO>();
        cfg.CreateMap<HumanDLO, HumanBLO>().AfterMap((src, dest) => dest.Tag = "mapped as Human");
        cfg.CreateMap<LionDLO, LionBLO>();
    });
}

[Test]
public void Test()
{
    var dlos = new List<AnimalDLO>
    {
        new HumanDLO(),
        new LionDLO()
    };

    var result = Mapper.Map<List<AnimalBLO>>(dlos);
    var human = result.First();

    Assert.IsInstanceOf(typeof(HumanBLO), human);
    Assert.AreEqual("mapped as Human", human.Tag);
} 

版本 4.2(可能 5.X)解决方案如下:

var config = new MapperConfiguration(cfg =>
{

    cfg.CreateMap<AnimalDLO, AnimalBLO>()
        .Include<HumanDLO, HumanBLO>()
        .Include<LionDLO, LionBLO>();

    cfg.CreateMap<HumanDLO, HumanBLO>();
    cfg.CreateMap<LionDLO, LionBLO>();
});

var dlos = new List<AnimalDLO>
{
    new LionDLO(),
    new HumanDLO(),
};

var result = config.CreateMapper().Map<List<AnimalBLO>>(dlos);