可以组成AutoMapper映射吗?

时间:2019-03-29 12:53:02

标签: c# automapper

我正在使用的模型包括一个入口对象,我想将其映射为子对象是整个对象。

这是问题的简化版本。我希望将OurWrappedSource的一个实例直接映射到OurTarget

class OurTarget
{
    public Guid Id { get; set; }
    public string Notes { get; set; }
    public int Quantity { get; set; }
}

class OurSource
{
    public Guid Id { get; set; }
    public string Notes { get; set; }
    public int Quantity { get; set; }
}

class OurWrappedSource
{
    public OurSource Source { get; set; }
}

private static void TestUnwrapUsingConfig(MapperConfiguration config)
{
    config.AssertConfigurationIsValid();
    IMapper mapper = new Mapper(config);

    var wrappedSource = new OurWrappedSource
    {
        Source = new OurSource
        {
            Id = new Guid("123e4567-e89b-12d3-a456-426655440000"),
            Notes = "Why?",
            Quantity = 27
        }
    };

    var target = mapper.Map<OurTarget>(wrappedSource);

    Assert.Equal(wrappedSource.Source.Id, target.Id);
    Assert.Equal(wrappedSource.Source.Notes, target.Notes);
    Assert.Equal(wrappedSource.Source.Quantity, target.Quantity);
}

以下配置有效,但对于多个成员来说是笨拙的:

// Works, but isn't *auto* enough
TestUnwrapUsingConfig(new MapperConfiguration(cfg =>
{
    cfg.CreateMap<OurWrappedSource, OurTarget>()
        .ForMember(src => src.Id, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Id))
        .ForMember(src => src.Notes, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Notes))
        .ForMember(src => src.Quantity, opts => opts.MapFrom(wrappedSource => wrappedSource.Source.Quantity));
}));

我想做的是定义两个中间映射,然后组成它们:

  1. OurWrappedSource直接映射到OurSource
  2. OurSource直接映射到OurTarget
  3. 通过将映射1与映射2组成映射,将OurWrappedSource映射到OurTarget

锤打一顿后,我的配置如下:

// Works, but #3 probably isn't ProjectTo-friendly
TestUnwrapUsingConfig(new MapperConfiguration(cfg =>
{
    // 1
    cfg.CreateMap<OurWrappedSource, OurSource>()
        .ConvertUsing(wrappedSource => wrappedSource.Source);

    // 2
    cfg.CreateMap<OurSource, OurTarget>();

    // 3
    cfg.CreateMap<OurWrappedSource, OurTarget>()
        .ConstructUsing((wrappedSource, ctx) =>
            ctx.Mapper.Map<OurTarget>(ctx.Mapper.Map<OurSource>(wrappedSource))
            )
        .ForAllOtherMembers(opts => opts.Ignore());
}));

这完全按照指定的方式工作,但是映射3似乎比它应该显示的更加明确和/或笨拙。它涉及到Func中的代码(而不是表达式),这使我认为与ProjectTo()一起使用时可能无法很好地进行优化。有没有办法重写映射3来解决这些问题?

0 个答案:

没有答案