问题
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:
Sorts destination type constructors by parameter count
destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length);
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