我正在使用Automapper将我的域模型(nHibernate)映射到我的视图模型并返回。一切都很顺利。
现在我需要将一个实体(域实体)映射到自身,因为我想在那里定义一些业务规则。
我需要多次为同一类型定义不同的映射。我已经为每种类型的映射使用了配置文件:
public static void Configure()
{
Mapper.Initialize(a =>
{
Mapper.AddProfile(new OrderViewModelMapperProfile());
Mapper.AddProfile(new OrderToOrder1MapperProfile());
Mapper.AddProfile(new OrderToOrder2MapperProfile());
});
}
这是我的个人资料(简化):
public class OrderToOrder1MapperProfile : Profile
{
protected override void Configure()
{
this.CreateMap<Domain.Order, Domain.Order>()
.WithProfile("Profile001")
.ForMember(dest => dest.Code, opt => opt.MapFrom(source => System.Guid.Empty))
.ForMember(dest => dest.OrderLines, opt => opt.Ignore())
.AfterMap((source, destination) =>
{
foreach (var line in source.OrderLines)
{
destination.AddOrderLine(Mapper.Map<Domain.OrderLine, Domain.OrderLine>(line));
}
});
this.CreateMap<Domain.OrderLine, Domain.OrderLine>()
.ForMember(dest => dest.Order, opt => opt.Ignore())
.ForMember(dest => dest.Code, opt => opt.MapFrom(source => System.Guid.Empty));
}
}
如您所见,我需要在AfterMap中做一些事情。
我的第二个配置文件OrderToOrder2MapperProfile看起来与此处显示的相似,因此我不会粘贴代码。
当我映射我的对象时:
Domain.Order order = new Domain.Order();
var order2 = Mapper.Map<Domain.Order, Domain.Order>(order);
两个配置文件都被处理。
我决定遵循SO 上建议的路径,并创建了我的“自定义”引擎:
private IMappingEngine CustomMappingEngine()
{
ConfigurationStore store = new ConfigurationStore(new TypeMapFactory(), MapperRegistry.Mappers);
MappingEngine engine = new MappingEngine(store);
store.AddProfile(new OrderToOrder2MapperProfile());
store.AllowNullDestinationValues = true;
store.AssertConfigurationIsValid();
return (engine);
}
现在一切正常,除了线的映射;即使我使用自定义引擎来映射我的对象,两个管道也会被处理:
Domain.Order order = new Domain.Order();
var newEngine = CustomMappingEngine();
var order2 = newEngine.Map<Domain.Order, Domain.Order>(order);
我想问题在于我在这里使用单例映射器(引擎):
destination.AddOrderLine(Mapper.Map<Domain.OrderLine, Domain.OrderLine>(line))
我试图找到一种在分析器中使用当前引擎的方法,但我似乎无法以任何方式获得它。
唯一可能的解决方案是在我的探查器的构造函数中传递引擎:
public class OrderToOrder2MapperProfile : Profile
{
private readonly IMappingEngine CurrentMappingEngine = null;
public OrderToOrder2MapperProfile(IMappingEngine mappingEngine)
{
this.CurrentMappingEngine = mappingEngine;
}
protected override void Configure()
{
this.CreateMap<Domain.Order, Domain.Order>()
.WithProfile("Profile002")
.ForMember(dest => dest.Code, opt => opt.MapFrom(source => System.Guid.Empty))
.ForMember(dest => dest.OrderLines, opt => opt.Ignore())
.AfterMap((source, destination) =>
{
foreach (var line in source.OrderLines)
{
destination.AddOrderLine(this.CurrentMappingEngine.Map<Domain.OrderLine, Domain.OrderLine>(line));
}
});
this.CreateMap<Domain.OrderLine, Domain.OrderLine>()
.ForMember(dest => dest.Order, opt => opt.Ignore())
.ForMember(dest => dest.Code, opt => opt.MapFrom(source => System.Guid.Empty));
}
}
并在此处使用当前引擎:
destination.AddOrderLine(this.CurrentMappingEngine.Map<Domain.OrderLine, Domain.OrderLine>(line));
问题:
这是唯一可能的解决方案还是有更好的选择?
我做事的方式正确吗?
如果有人感兴趣,我已经创建了一个使用StructureMap作为测试用例的github 存储库。