10

I have to do some object to object mapping between domain classes used in a C# project and classes which are sent to flash clients.

My first choice was Automapper. But I've had some issues with it (nested properties, no parameterless constructor defined). It turns out that it is not so easy to map a really complex type with Automapper.

Why not implement methods like the following?

  ClassA GetClassAByClassB(ClassB pObj)

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

It has exactly the same level of flexibility as mapping done using Automapper. You still have to provide which property from the source object is copied into what property in destinations object. You just do this using = instead of a lambda expression.

But if you change something in your domain classes you have to change this "mapping" part anyway. What, then, is the main advantage to using Automapper over literal mappings?

ruffin
  • 16,507
  • 9
  • 88
  • 138
Katalonis
  • 691
  • 2
  • 6
  • 16

3 Answers3

7

The one benefit that AutoMapper claims is mapping-by-convention. Here is a quote from "AutoMapper Introduction and Samples"

Herein lies the beauty of AutoMapper. When your classes align themselves conventionally, your mapping configuration can be as simple

This comes with a cost. Renaming or changing either the target or the source property name will break the mapping and introduce a run-time bug.

If you do not use mapping-by-convention, AutoMapper loses its advantage. In this case, I'd rather write a factory function like this one.

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

Then you would construct the destination object like

var classA = classB.MapToClassA();

instead of

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

Personally, I'd prefer a factory function for its explicitness, readability, and debug friendliness. Good luck with trying to find out, in the second case, how ClassB is mapped to ClassA, whether the mapping profile is loaded, or why there is an exception when the Map<>() function is called, or why some of the properties have been assigned wrong values.

Xiaoguo Ge
  • 2,177
  • 20
  • 26
7

Sometimes using mappers, it is very difficult to trace the bugs. For eg., if we misspelt Employee in data class with Emplyee in view model class, mappers like tiny mappers doesn't throw any exceptions unless we explicitly set the mappers as strict mapping, and during that time code compiles and runs perfectly but we are unable to trace mistakes. This situation rarely happens with manual mapping, so manual mapping of objects have some advantages over auto mapping.

ank2k11
  • 69
  • 1
  • 2
6

Because with AutoMapper you don't have to implement those methods ;-)

Your approach requires writing a lot of

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

AutoMapper uses conventions to figure it itself. What is more, you don't have to worry about pObj == null (your code will throw NulLReferenceException in this case).

You can also define conversions in your map (ie. string to DateTime).

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

AutoMapper supports nested properties as well.

Read more here: AutoMapper Introduction and Samples

Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126
  • What about properties which dont have the same names? And nested Properties? I think I should change conventions, but sometimes property on one side is 'PositionX' and on he other side just 'X'. (just an example - the properties anmes might be quite unpredictable). So isnt it like I should not use Automapper in my case? – Katalonis Oct 22 '10 at 11:23
  • @Katalonis - Then you configure the mapper in the type-safe manner using lambdas. Added a code sample and link. – Jakub Konecki Oct 22 '10 at 11:58
  • Course flip side is that if you see more `dest.MyProp, opt => opt.Ignore()` or `dest.MyProp, opt => opt.MapFrom(src => Transformation(src.MyProp))` than you gained through automapping, it's less great. Or, as [ank2k11 points out](https://stackoverflow.com/a/50094249/1028230), beware when map-by-magic-string-convention falls on its face. [Xiaoguo hits nail on its head](https://stackoverflow.com/a/41754539/1028230): "**_When your classes align themselves conventionally**, your mapping configuration can be as simple_". Otherwise you actually _are_ implementing those methods, just w/in AutoMapper. – ruffin Oct 05 '21 at 21:00