Каковы преимущества использования Autopper?

Мой вопрос может быть глупым, но я уверен, что пропустил очень важную часть проблемы. Мне нужно сделать отображение объекта на объект (между классами домена, используемыми в проекте C#, и классами, которые отправляются флеш-клиентам).

Мой первый выбор был Automapper. Но у меня были некоторые проблемы с этим (вложенные свойства, не определяемый конструктор без параметров). Оказывается, не так просто сопоставить действительно сложный тип с автоматом.

Тогда мой вопрос: почему бы не реализовать такие методы, как:

  ClassA GetClassAByClassB(ClassB pObj)

   {  
     ClassA objA = new ClassA();  
     objA.Prop1 = pObj.Prop1;  
     objA.NestedType.Prop2 = pObj.Prop2;  
     //....Some more.....  
     return objA;  
   }  

Он имеет тот же уровень гибкости, что и отображение, выполненное с использованием Automapper. Вы все еще должны указать, какое свойство из исходного объекта копируется в какие свойства объекта назначения. Вы просто делаете это, используя '=', а не лямбда-выражение.

Но если вы что-то измените в своих классах домена, вам все равно придется изменить эту часть "отображения". Итак, что является главным, что должно убедить меня в использовании Automapper (как я уже говорил в начале, я почти уверен, что упускаю что-то важное).

3 ответа

Решение

Потому что с AutoMapper вам не нужно реализовывать эти методы;-)

Ваш подход требует написания много

classA.propA = classB.propA;
classA.propB = classB.propB;
classA.propC = classB.propC;
classA.propD = classB.propD;
classA.propE = classB.propE;

AutoMapper использует соглашения, чтобы понять это сам. Более того, вам не нужно беспокоиться о pObj == null (ваш код скинет NulLReferenceException в этом случае).

Вы также можете определить преобразования на вашей карте (например, строка в DateTime).

Mapper.CreateMap<User, UserModel>().ForMember(d => d.LastLogin, c => c.MapFrom<DateTime?>(u => u.Credential.LastLogin));

AutoMapper также поддерживает вложенные свойства.

Подробнее здесь: Введение в AutoMapper и примеры

Единственное преимущество, которое, как утверждает AutoMapper, заключается в сопоставлении по соглашению. Вот цитата из "Введение и образцы AutoMapper"

"В этом и заключается прелесть AutoMapper. Когда ваши классы выровняются традиционным образом, ваша конфигурация отображения может быть настолько простой"

Эта выгода идет с ценой. Переименование или изменение как целевого, так и исходного свойства нарушит отображение и приведет к ошибкам во время выполнения, а не к ошибкам компиляции.

Если вы не можете полагаться на условное отображение, AutoMapper теряет свое преимущество. В этом случае я бы предпочел написать заводскую функцию, как показано ниже.

public static ClassA MapToClassA(this ClassB b)
{
    return new ClassA()
    {
        propA = b.propA;
        propB = b.propB;
        propC = b.propC;
    }
}

Тогда вы бы построить объект назначения как

var classA = classB.MapToClassA();

вместо

var classA = Mapper.Map<ClassB, ClassA>(classB)

Лично я предпочел бы фабричные функции, даже когда сопоставление соглашения возможно из-за его явности, читабельности и удобства отладки. Удачи при попытке выяснить, во втором случае, как ClassB отображается на ClassA, загружен ли профиль отображения, или почему существует исключение при вызове функции Map<>(), или почему некоторые свойства было присвоено неправильное значение.

Иногда с помощью картографов очень сложно отследить ошибки. Например, если мы неправильно опишем Employee в классе данных с Emplyee в классе модели представления, преобразователи типа крошечных преобразователей не выдают никаких исключений, если только мы явно не установим преобразователи как строгое сопоставление, и в течение этого времени код компилируется и работает отлично, но мы не в состоянии отследить ошибки. Такая ситуация редко возникает при ручном сопоставлении, поэтому ручное сопоставление объектов имеет некоторые преимущества перед автоматическим сопоставлением.

Другие вопросы по тегам