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?
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.
Sign up to join this communityAutomapper 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:
http://www.codeproject.com/Articles/61629/AutoMapper
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.
Is the duplication of classes ever useful/good design?
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.
Programming is the art of telling another human what one wants the computer to do. - Donald Knuth
With this in mind, ask yourself "is AutoMapper helpful today and will it be tomorrow?"
In my experience, when someone has complained about 'too much boilerplate' and wants to use AutoMapper, it's been one of the following:
However:
If you've picked a statically-typed language, then take advantage of the language. If you are attempting to circumvent the controls in the language that help prevent mistakes due to over-use of reflection and magic APIs like AutoMapper, it just means you've picked a language that's unsatisfactory for your needs.
Also, just because Microsoft added features to C# does not mean they are fair game in every situation or that they support best practice. Reflection and the 'dynamic' keyword, for example, should be used in cases where you simply cannot accomplish what you need without them. AutoMapper is not a solution for any use case that cannot already be solved without it.
So, is duplication of classes bad design? Not necessarily.
Is AutoMapper a bad idea? Yes, absolutely.
Use of AutoMapper indicates systemic deficiencies in the project. If you find yourself needing it, stop and think about your design. You'll always find a better, more readable, more maintainable and more bug-free design.
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. class MyPoint2D
and class YourPoint2D
are separate types even if they have the exact same definitions. When the type you want is "some anonymous thing with an x
field and a y
field" (i.e. a record), you're out of luck. So when you want to turn a YourPoint2D
into a MyPoint2D
, you have three options:
this.x = that.x; this.y = that.y
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.
Automapper is one of those libraries/tools where the emperor is literally running around butt naked. When you get past the glitzy logo, you realize it doesn't do anything you can't do manually with much better results.
While I'm not entirely sure how it hints at auto-mapping members, it most likely involves additional runtime logic and possible reflection. This may be a significant performance penalty in exchange for a time savings. Manual mapping, on the other hand, the hinting is executed well before compile time.
In cases where AutoMapper has no clue, you must configure the mapping with code and setting flags. If you’re going to bother doing all the setup and code work, you have to question how much it saves over manual mapping.