1

我正在使用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 存储库。

4

0 回答 0