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.
At the time of writing this answer, AutoMapper will do this automatically (with a simple CreateMap<>() call) for you if the properties match the constructor parameters.
The Automapper Reverse Mapping is nothing but the two-way mapping which is also called as bidirectional mapping.
So, the AutoMapper Ignore() method is used when you want to completely ignore the property in the mapping. The ignored property could be in either the source or the destination object.
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.
Here's an extension method...
public static void CreateMapWithDefaultConstructor<T, TU>(this Profile profile) where TU : class, new() { profile.CreateMap<T, TU>().ConstructUsing(source => new TU()); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With