Подтвердить что ты не робот

AutoMapper с использованием неправильного конструктора

Сегодня я обновил полностью работоспособное приложение, используя 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;}
}

...

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

Но я продолжал получать ошибку "Неоднозначный вызов", которую я не мог решить.

Затем я попробовал

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

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

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

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

4b9b3361

Ответ 1

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

Func<ResolutionContext, TypeOne>

Вот код:

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

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

  • Сортирует конструкторы типа назначения по количеству параметров

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