AutoMapper using the wrong constructor

天大地大妈咪最大 提交于 2019-12-21 03:12:40

问题


Today I upgraded a fully functioning application using AutoMapper v1.1 to now use AutoMapper v2.1 and I am coming across some issues that I never encountered using the previous version.

Here is an example of my code mapping back from Dto to Domain object

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);

However the first problem I encountered with v2.1 was that AutoMapper was trying to use the constructor with 2 args when one of the args was null and should be using the 1 arg constructor.

I then tried to use

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

But I kept getting an 'Ambiguous Invocation' error that I couldn't resolve.

I then tried

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

and that did successfully create the TypeOne object using the parameterless constructor but then it failed to set the private setter properties.

I have looked for help on the AutoMapper website and downloaded the source code to have a good look but didn't get far with the little documentation about and there were not many unit tests for ConstructUsing.

Is there anything obvious I am missing that I should change with v2.1? I am surprised that it has changed so much from v1.1.


回答1:


You just need to add explicit cast to

Func<ResolutionContext, TypeOne>

Here is the code:

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

Current version of AutoMapper works as described below:

  1. Sorts destination type constructors by parameter count

    destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length);
    
  2. Takes first constructor which parameters match source properties (without any check for null value). In your case it is constructor with two parameters.



来源:https://stackoverflow.com/questions/11147347/automapper-using-the-wrong-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!