我们正在将 domain 层次结构映射到 Dto 层次结构,并使用 ReverseMap() 来简化映射回 domain 的过程。
把所有的单独派生都包含到映射中是相当烦人的。这就是为什么我们尝试使用IncludeAllDerived()。这在一段时间内确实很好用,但过了一段时间后,我们就出现了奇怪的异常。
System.ArgumentException : Cannot create an instance of abstract type Xxx.Base
经过调查,我们发现这是因为使用了IncludeAllDerived(). 当我们把它改成显式的include时,它又开始工作了。
我们问自己的问题是:"是IncludeAllDerived还是ReverseMap,还是Automapper不能处理抽象的基类型或其他什么"。
一些进一步的调查表明,IncludeAllDerived和ReverseMap的组合是一个问题。如果我们在ReverseMap之后重复IncludeAllDerived,那么它就能像预期的那样工作。
以下是重现的代码(Automapper 9.0.0)。
public abstract class Base { }
public class Derived: Base { }
public abstract class BaseDto { }
public class DerivedDto: BaseDto { }
[Test]
public void MappingBase_WithReverseMap_AllDerived()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Base, BaseDto>()
.IncludeAllDerived()
.ReverseMap()
.IncludeAllDerived(); // doesn't work without repeating IncludeAllDerived() after ReverseMap()
cfg.CreateMap<Derived, DerivedDto>()
.ReverseMap();
});
var mapper = configuration.CreateMapper();
BaseDto derivedDto = new DerivedDto();
var vm = mapper.Map<Base>(derivedDto);
vm.Should().NotBeNull();
vm.Should().BeOfType<Derived>();
}
[Test]
public void MappingBase_WithReverseMap_IncludeBase()
{
var configuration = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Base, BaseDto>()
.Include<Derived, DerivedDto>()
.ReverseMap(); // works without repeating Include() after ReverseMap()
cfg.CreateMap<Derived, DerivedDto>()
.ReverseMap();
});
var mapper = configuration.CreateMapper();
BaseDto derivedDto = new DerivedDto();
var vm = mapper.Map<Base>(derivedDto);
vm.Should().NotBeNull();
vm.Should().BeOfType<Derived>();
}