继承映射
集成映射有两个功能:
- 从基类或配置接口集成映射配置.
- 运行多态映射
继承基类配置是可选的, 你可以使用 Include
显式的指定映射来继承基类配置, 或者在派生类中通过 IncludeBase
来配置:
CreateMap<BaseEntity, BaseDto>()
.Include<DerivedEntity, DerivedDto>()
.ForMember(dest => dest.SomeMember, opt => opt.MapFrom(src => src.OtherMember));
CreateMap<DerivedEntity, DerivedDto>();
或者
CreateMap<BaseEntity, BaseDto>()
.ForMember(dest => dest.xxx, opt => opt.MapFrom(src => src.xxx));
CreateMap<DerivedEntity, DerivedDto>()
.IncludeBase<BaseEntity, BaseDto>();
上面的两段代码都可以在派生映射中继承基映射的配置.
Include
/ IncludeBase
具有递归的特性, 因此只需要配置继承结构上最近的两个类型即可.
如果需要作用所有的派生类, 可以使用 IncludeAllDerived()
方法. 但需要注意性能问题. 这样会扫描所有派生类.
CreateMap<BaseENtity, BaseDto>()
.IncludeAllDerived();
CreateMap<DerivedEntity, DerivedDto>();
运行时多态
存在多个派生类, 同时又配置了多个派生类的映射时, 可以在 Map
的时候指定被目标类型.
public class Order { }
public class OnlineOrder : Order { }
public class MailOrder : Order { }
public class OrderDto { }
public class OnlineOrderDto : OrderDto { }
public class MailOrderDto : OrderDto { }
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Order, OrderDto>()
.Include<OnlineOrder, OnlineOrderDto>()
.Include<MailOrder, MailOrderDto>();
cfg.CreateMap<OnlineOrder, OnlineOrderDto>();
cfg.CreateMap<MailOrder, MailOrderDto>();
});
// Perform Mapping
var order = new OnlineOrder();
var mapped = mapper.Map(order, order.GetType(), typeof(OrderDto));
Assert.IsType<OnlineOrderDto>(mapped);
上述代码使用了 Map
的重载
在派生类中指定继承 (待验证)
绕过从基类集成, 在子类中指定集成
var configuration = new MapperConfiguration(cfg => {
cfg.CreateMap<Order, OrderDto>()
.ForMember(o => o.Id, m => m.MapFrom(s => s.OrderId));
cfg.CreateMap<OnlineOrder, OnlineOrderDto>()
.IncludeBase<Order, OrderDto>();
cfg.CreateMap<MailOrder, MailOrderDto>()
.IncludeBase<Order, OrderDto>();
});
案例只有两层集成关系, 有待验证在三层, 四层或更多层集成关系中, 是否可以从中间指定.
As
简单情况下, 可以使用 As
将基映射从定向导已存在的派生映射上
cfg.CreateMap<Order, OnlineOrderDto>();
cfg.CreateMap<Order, OrderDto>().As<OnlineOrderDto>();
mapper.Map<OrderDto>(new Order()).ShouldBeOfType<OnlineOrderDto>();
继承映射的优先级
这部分主题较复杂, 因为可以映射属性的方式有很多. 决定优先级的顺序为:
- 显式映射 (使用
.MapFrom()
) - 显式继承映射
- 忽略属性映射
- 默认约定映射 (通过约定来匹配属性)
jk: 文档比较生硬, 而且逻辑层次不清. 常常会在很多主题中混入其他主题的内容. 对于初学使用者并不友好. 还是应该再整理一篇. 2024年1月2日