【问题标题】:AutoMapper mapping object typesAutoMapper 映射对象类型
【发布时间】:2020-07-08 18:42:23
【问题描述】:

我正在处理一组非常糟糕的生成类,这些类具有大量对象类型的属性,其中包含我想要映射的各种类型。类映射似乎有效,但是属性引用只是直接复制而不映射引用的对象。

如何定义映射 Items 属性内的对象的映射?我有很多这样的对象,所以希望我可以相当简单地定义它......

例子:

    class Program
{
    static void Main(string[] args)
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<TerribleType1, TerribleType1Dto>();
            cfg.CreateMap<TerribleType2, TerribleType2Dto>();
            cfg.CreateMap<TerribleObject, TerribleObjectDto>();
        });

        var mapper = config.CreateMapper();
        var terribleObject = new TerribleObject
        {
            Items = new object[] { new TerribleType1 { PropA = "Test1" }, new TerribleType2 { PropA = "Test2" } }
        };

        var terribleObjectDto = mapper.Map<TerribleObjectDto>(terribleObject);
        
        //Want a TerribleType1Dto but instead I get a TerribleType1
        Console.WriteLine(terribleObjectDto.Items[0].GetType().Name);
    }
}

class TerribleObject
{
    // Contains some TerribleType1 and TerribleType2 objects, these don't share a common base.
    public object[] Items { get; set; }
}

class TerribleObjectDto
{
    //Want this to have some TerribleType1Dto and TerribleType2Dto objects.
    public object[] Items { get; set; }
}

public class TerribleType1
{
    public string PropA { get; set; }
}

public class TerribleType1Dto
{
    public string PropA { get; set; }
}

public class TerribleType2Dto
{
    public string PropA { get; set; }
}

public class TerribleType2
{
    public string PropA { get; set; }
}

【问题讨论】:

  • 你考虑过使用反射吗?
  • @LucianBargaoanu 我阅读了文档。如果您有答案,请提供,我很乐意接受。我尝试使用带有 .Include 的 映射配置。这会导致运行时错误。似乎 AutoMapper 不仅限于包含的类型,而是所有从对象派生的类型。这显然是个问题。
  • @Tarik 我想我可以。哈哈,到目前为止,我已经使用 AutoMapper,它适用于我 90% 的对象。我宁愿现在不回头或拥有两个对象映射器,但如果必须,我想我可以。

标签: c# automapper


【解决方案1】:

基于How can I use Automapper to map an object to an unknown destination type?,当您仅在运行时知道源类型时,可以获得为映射配置的目标类型。在MapFrom() 的帮助下,可以为内部object 类型对象构建这个丑陋的映射:

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<TerribleType1, TerribleType1Dto>();
    cfg.CreateMap<TerribleType2, TerribleType2Dto>();
    cfg.CreateMap<TerribleObject, TerribleObjectDto>()
       .ForMember(t => t.Items, m => m.MapFrom((source, target, data, context) =>
       {
           object[] items = source.Items;
           object[] targetArray = new object[items.Length];
           for (int i = 0; i < items.Length; i++)
           {
               object fieldEntry = items[i];
               Type destinationType = context.Mapper.ConfigurationProvider
                   .GetAllTypeMaps()
                   .Single(it => it.SourceType == fieldEntry.GetType())
                   .DestinationType;
               targetArray[i] = context.Mapper.Map(fieldEntry,
                                                   fieldEntry.GetType(), 
                                                   destinationType);
           }
           return targetArray;
       }));
});

这会将数组中的每个object 转换为配置的目标类型。现在运行代码时:

Console.WriteLine(terribleObjectDto.Items[0].GetType().Name);
Console.WriteLine(terribleObjectDto.Items[1].GetType().Name);

你会得到以下输出:

TerribleType1Dto
TerribleType2Dto

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-11
    • 2017-12-23
    • 2017-07-20
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多