Automapper is an "object-object mapper" for .Net, which means copying objects from a class into another class that represents the same thing.
Why is this ever useful? Is the duplication of classes ever useful/good design?
A quick google search revealed this example:
showing a perfectly valid usage of AutoMapper which is definitely not an example for a poor design. In a layered application, you may have objects in your data or business layer, and you sometimes need just a subset of the attributes of that data objects, or some kind of view to them in your UI layer. So you create a view model which contains objects with exactly the attributes you need in your UI, not more, and use AutoMapper to provide the content of that objects with less boilerplate code.
In such a situation your "view objects" are not a duplicate of the original class. They have different methods and perhaps a few duplicate attributes. But that's ok as long as you use that view objects only for UI displaying purposes and don't start to misuse them for data manipulation or business operations.
Another topic you may read to get a better understanding of this is Fowlers Command Query Responsibility Segregation pattern, in contrast to CRUD. It shows you situations where different object models for querying data and updating them in a database make sense. Here, mapping from one object model to another may also be done by a tool like AutoMapper.
|show 4 more comments|
Its good practice to have a separate view model class for use in the UI layer rather than using the same class that's used in the data layer. Your UI/web page might need to display other bits of information that aren't strictly related to the data entity. By creating this extra class, you are giving yourself the freedom to tweak your UI easily as requirements change over time.
As far as using AutoMapper goes, I personally avoid it for 3 reasons:
Silent failures more common
Because AutoMapper maps between properties automatically, changing a property name on one class and not the other will cause the Property mapping to be skipped. The compiler won't know. Automapper won't care.
Lack of static analysis
So you've been given a large code base to deal with. There's a million classes with a million properties. Alot look like they aren't used, or are duplicates. That "Find all references" tool in Visual Studio will help you see where properties are used and help build a map in your head of how the whole application hangs together. But wait, there's no explicit references to half the properties because Automapper is being used. My job is now a hell of a lot harder.
Late requirements that increase complexity
Automapper is all fine and dandy when all you want to do is copy the values from ONE class to another (as is often the case at the START of development), but remember those requirements that change over time? What if you now need to get values from other parts of your application, perhaps specific to the user that's logged in or some other contextual state?
AutoMapper's pattern of creating the one-to-one class mappings at application start doesn't lend itself well to these sorts of context-specific changes. Yes, there's probably ways of making it work, but I usually find it cleaner, simpler and more expressive to write the logic myself.
In summary, before reaching for Automapper to save yourself 30 seconds of manually mapping one class to another, think about this.
With this in mind, ask yourself "is AutoMapper helpful today and will it be tomorrow?"
There is a deeper issue here: the fact that C# and Java insist most/all types must be distinguishable by name rather than structure: e.g.
Choice 1 is easy enough in small doses but quickly becomes a chore when the number of types you need to map is large.
Choice 2 is less than desirable because now you have to add an extra step to your build process to generate the code, and make sure the entire team gets the memo. In the worst case you have to roll your own code generator or template system too.
That leaves you with reflection. You could do it yourself, or you could use AutoMapper.