AutoMapper使用错误的构造函数

Mar*_*ery 26 c# automapper automapper-2

今天我使用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;}
}
Run Code Online (Sandbox Code Playgroud)

...

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

var typeOne = Mapper.Map<TypeOne>(typeOneDto);
Run Code Online (Sandbox Code Playgroud)

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

然后我试着用

Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(x => new TypeOne());
Run Code Online (Sandbox Code Playgroud)

但我不断收到一个"模糊调用"错误,我无法解决.

然后我试过了

Mapper.CreateMap<TypeOneDto, TypeOne>().ConvertUsing(x => new TypeOne());
Run Code Online (Sandbox Code Playgroud)

并且使用无参数构造函数成功创建了TypeOne对象,但是它无法设置私有setter属性.

我已经在AutoMapper网站上寻求帮助并下载了源代码以获得良好的外观,但是没有得到很少的文档,并且没有很多针对ConstructUsing的单元测试.

有什么明显的我想念我应该用v2.1改变吗?我很惊讶它从v1.1发生了很大的变化.

k0s*_*tya 50

你只需要添加显式强制转换

Func<ResolutionContext, TypeOne>
Run Code Online (Sandbox Code Playgroud)

这是代码:

Mapper.CreateMap<TypeOneDto, TypeOne>().ConstructUsing(
            (Func<ResolutionContext, TypeOne>) (r => new TypeOne()));
Run Code Online (Sandbox Code Playgroud)

当前版本的AutoMapper的工作原理如下:

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

    destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 获取第一个构造函数,其中哪些参数与源属性匹配(不检查空值).在您的情况下,它是具有两个参数的构造函数.

  • 虽然这是一个相当古老的帖子,但我很高兴我找到了它:AutoMapper认为匹配构造函数的顺序似乎已经在4.0.4版本中再次发生了变化.为避免出现问题,如果您有多个构造函数,则可以在更保守的方面指定AutoMapper应使用哪个构造函数.此外,作为第二个建议,进行自动化测试,设置所有地图然后调用`Mapper.AssertConfigurationIsValid()`.这样你就可以在早期解决问题.快乐的编码! (3认同)