2012-06-21 5 views
25

Сегодня я обновил полностью работоспособное приложение, используя AutoMapper v1.1, чтобы теперь использовать AutoMapper v2.1, и я сталкиваюсь с некоторыми проблемами, с которыми я никогда не сталкивался, используя предыдущую версию.AutoMapper с использованием неправильного конструктора

Вот пример моего отображения кода обратно от 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 аргументами, когда один из аргументов был нулевым и должен использовать конструктор 1 arg.

Затем я попытался использовать

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

Но я продолжал получать ошибку «Неоднозначное Invocation», что я не мог решить.

Затем я попытался

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

и что было успешно создать объект TypeOne с помощью конструктора без параметров, но тогда это не удалось установить личные свойства сеттер.

Я искал помощь на веб-сайте AutoMapper и загрузил исходный код, чтобы иметь хороший внешний вид, но не зашел далеко за небольшую документацию и не было много модульных тестов для ConstructUsing.

Есть ли что-то очевидное, что мне не хватает, что я должен изменить с помощью v2.1? Я удивлен, что он сильно изменился с v1.1.

+0

возможно дубликат [Automapper - как привязать к параметрам конструктор вместо сеттеров свойств] (http://stackoverflow.com/questions/2239143/automapper-how-to-map-to-constructor-parameters- вместо-property-setters) –

+0

Я продолжаю получать ту же ошибку, о которой я упоминал выше при использовании «ConstructUsing». «Неоднозначный вызов», когда я создаю новый объект с конструктором без параметров. –

ответ

48

Вам просто нужно добавить explicit cast к

Func<ResolutionContext, TypeOne> 

Вот код:

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

Текущая версия AutoMapper работает, как описано ниже:

  1. ОБР.ПОР назначения конструкторы типа по количеству параметров

    destTypeInfo.GetConstructors().OrderByDescending(ci => ci.GetParameters().Length); 
    
  2. Принимает первый конструктор, параметры которого соответствуют свойствам источника (без проверки нулевого значения). В вашем случае это конструктор с двумя параметрами.

+0

Это только спасло меня от печали. Отлично работает на последней версии AutoMapper (3.2.1.0) :) Спасибо! – Stu1986C

+3

Хотя это довольно старый пост, я рад, что нашел его: Последовательность того, что AutoMapper считает совпадением для конструктора, похоже, снова изменилась с версией 4.0,4. Чтобы избежать проблем, на более консервативной стороне всегда можно указать, какой конструктор AutoMapper должен использовать, если у вас более одного конструктора. Кроме того, в качестве второй рекомендации у вас есть автоматизированный тест, который устанавливает все карты, а затем вызывает «Mapper.AssertConfigurationIsValid()». Таким образом, вы можете ввести в действие проблемы на раннем этапе. Счастливое кодирование! – Manfred

Смежные вопросы