Reputation: 701
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?
Upvotes: 11
Views: 9930
Reputation: 2328
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.
Upvotes: 7
Reputation: 69
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.
Upvotes: 7
Reputation: 46008
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
Upvotes: 6