自动映射器:无法在列表和从列表派生的模型之间映射

问题描述 投票:0回答:1

当我映射派生自列表的对象时,我收到错误

Incorrect number of arguments supplied for call to method System.String 'get_Item(Int32)'
。 但是,如果我使用 #3597 中的修复,映射器将运行,但结果为空。

来源/目的地类型

public class ListExtension : List<string>
  {
  }

映射配置

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<ListExtension, List<string>>()
        .ForMember("Item", op => op.Ignore());
    cfg.CreateMap<List<string>, ListExtension>()
        .ForMember("Item", op => op.Ignore());
});

IMapper mapper = config.CreateMapper();

预期行为

列表映射到“ListExtension”,它派生自与列表相同的类型。在重现示例中,我希望测试能够通过。

实际行为

当我映射列表时,收到错误“为调用方法 System.String get_Item(Int32) 提供的参数数量不正确”。

但是,我使用 #3597 中的修复,映射器将运行,但结果为空。在再现示例中,测试未通过。

重现步骤

[Fact]
public void Issue1()
{
    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<ListExtension, List<string>>()
            .ForMember("Item", op => op.Ignore());
        cfg.CreateMap<List<string>, ListExtension>()
            .ForMember("Item", op => op.Ignore());
    });

    IMapper mapper = config.CreateMapper();

    List<string> myList = new List<string> { "0", "1", "2" };

    var afterMap = mapper.Map<ListExtension>(myList);
    Assert.Equal(myList.Count, afterMap.Count);
}
c# automapper
1个回答
0
投票

您可以采用稍微不同的方法,使用实现

AutoMapper.ITypeConverter<in TSource, TDestination>
通用接口的自定义转换器来使映射配置正常工作。

转换器类需要公开一个包含映射逻辑的

TDestination Convert(TSource source, TDestination destination, ResolutionContext context)
方法

因此,对于您发布的示例,更改将如下所示 -

// class inheriting from List<string>
public class ListExtension : List<string>
{
}

// converter class containing mapping logic
public class ListToListExtensionConverter : ITypeConverter<List<string>, ListExtension>
{
    public ListExtension Convert(List<string> source, ListExtension destination, ResolutionContext context)
    {
        if (destination == null)
            destination = new ListExtension();

        foreach (var item in source)
        {
            destination.Add(item);
        }

        return destination;
    }
}

// mapper configuration that uses the converter logic
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<List<string>, ListExtension>().ConvertUsing<ListToListExtensionConverter>();
});

最终测试方法将如下所示 -

[Fact]
public void Issue1()
{
    var config = new MapperConfiguration(cfg =>
    {
        cfg.CreateMap<List<string>, ListExtension>().ConvertUsing<ListToListExtensionConverter>();
    });

    IMapper mapper = config.CreateMapper();

    List<string> myList = new List<string> { "0", "1", "2" };

    var afterMap = mapper.Map<ListExtension>(myList);
    Assert.Equal(myList.Count, afterMap.Count);

}
© www.soinside.com 2019 - 2024. All rights reserved.