28

今天,我使用 AutoMapper v1.1 升级了一个功能齐全的应用程序,现在使用 AutoMapper v2.1,我遇到了一些使用以前版本从未遇到过的问题。

这是我的代码从Dto映射回对象的示例

public class TypeOne
{
   public TypeOne()
   {
   }

   public TypeOne(TypeTwo two)
   {
      //throw ex if two is null
   }

   public TypeOne(TypeTwo two, TypeThree three)
   {
      //throw ex if two or three are null
   }

   public TypeTwo Two {get; private set;}

   public TypeThree Three {get; private set;}
}

public class TypeOneDto
{
   public TypeOneDto()
   {
   }

   public TypeTwoDto Two {get; set;}

   public TypeThreeDto Three {get; set;}
}

...

Mapper.CreateMap<TypeThreeDto, TypeThree>();
Mapper.CreateMap<TypeTwoDto, TypeTwo>();
Mapper.CreateMap<TypeOneDto, TypeOne>();

var typeOne = Mapper.Map<TypeOne>(typeOneDto);

然而,我在 v2.1 中遇到的第一个问题是 AutoMapper 尝试使用带有 2 个 args 的构造函数,而其中一个 args 为 null 并且应该使用 1 个 arg 构造函数。

然后我尝试使用

Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(x => new TypeOne());

但是我不断收到无法解决的“模糊调用”错误。

然后我尝试了

Mapper.CreateMap<TypeOneDto, TypeOne>().ConvertUsing(x => new TypeOne());

并且确实使用无参数构造函数成功创建了 TypeOne 对象,但随后它未能设置私有 setter 属性。

我已经在 AutoMapper 网站上寻求帮助并下载了源代码以进行查看,但没有得到太多关于 ConstructUsing 的小文档并且没有太多单元测试。

有什么明显的我遗漏的东西我应该用 v2.1 改变吗?我很惊讶它与 v1.1 相比发生了如此大的变化。

4

2 回答 2

53

你只需要添加明确的 演员表

Func<ResolutionContext, TypeOne>

这是代码:

Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(
            (Func<ResolutionContext, TypeOne>) (r => new TypeOne()));

当前版本的 AutoMapper 的工作方式如下所述:

  1. 按参数计数对目标类型构造函数进行排序

    destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length);
    
  2. 采用参数匹配源属性的第一个构造函数(不检查空值)。在您的情况下,它是具有两个参数的构造函数。

于 2012-06-27T12:04:40.493 回答
1

这是一个扩展方法...

    public static void CreateMapWithDefaultConstructor<T, TU>(this Profile profile)
        where TU : class, new()
    {
        profile.CreateMap<T, TU>().ConstructUsing(source => new TU());
    }
于 2020-05-26T17:45:07.267 回答