29

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?

27

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.

  • 1
    Regarding your first example: couldn't you compose objects instead of duplicating them? In that case your UI objects would have a reference to your original data objects, and would expose only the necessary elements. Wouldn't that make sense? – static_rtti Oct 3 '12 at 13:51
  • 1
    @static_rtti in theory yes, but you may not necessarily want your original class to be public or/and exposed in an assembly – Jalayn Oct 3 '12 at 14:04
  • 2
    @static_rtti: yes, that is a perfectly valid, different approach. The main difference between those two designs is the lifetime of the data/attributes. Using copies provides you with a snapshot of the data, using properties referencing the original data does not. Both approaches have its pros and cons, but IMHO there is no "better or worse" in general. Additionally, there may be performance considerations, which may or may not influence the decision what to use. – Doc Brown Oct 3 '12 at 14:06
  • 3
    Decoupling as much as possible is always a good idea. Not because it's particularly beneficial for even small projects, but because projects grow. – Tamás Szelei Oct 3 '12 at 14:25
  • 5
    @fish: I agree mostly, decoupling is often a good idea, but IMHO there are enough situations where keeping things simple outweighs a multi-layer-super-decoupled-for-the-sake-of-decoupling approach. The hard part is not to miss the point during the growth of a project when one should start refactoring. – Doc Brown Oct 3 '12 at 14:35
39

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?"

  • [if you do trendy web dev] So if you are writing a REST web service do you tend to always check each and every property to make sure your JavaScript object model is consistent with your .NET object model? – Den Jul 9 '14 at 12:00
  • 2
    @Den - yes. And you write tests to make sure you get all the properties correct (ie your test will show any properties that you've added in 1 place that do not get propagated to the other tiers) – gbjbaanb Jul 9 '14 at 12:36
  • @gbjbaanb I would probably just use reflection to do this validation in a generic way. Perhaps explore the possibility of extending AutoMapper to add some validation. Would definitely avoid lots of manual assignments. – Den Jul 9 '14 at 14:40
  • Totally Agree with you and think only very simple apps can use automapper, but when things come more complex we need to write new configuration for automapper then why not write those in a manual mapper helper or service. – ahmedsafan86 Jan 13 at 13:22
17

In my experience, when someone has complained about 'too much boilerplate' and wants to use AutoMapper, it's been one of the following:

  1. They find it irritating to write the same code over and over.
  2. They are lazy and don't want to write code that does A.x = B.x.
  3. They are under too much time pressure to actually think about whether writing A.x = B.x over and over is a good idea and then write good code for the task.

However:

  1. If it's truly about avoiding repetition, you can create an object or method to abstract it. You don't need AutoMapper.
  2. If you are lazy, you'll be lazy and won't learn how AutoMapper works. Instead you'll adopt the 'programming by coincidence' pattern and write horrible code where you stuff business logic in an AutoMapper profile. In this case, you should change your attitude towards programming or find something else to do as a profession. You don't need AutoMapper.
  3. If you are under too much time pressure, your problem doesn't have anything to do with programming itself. You don't need AutoMapper.

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.

  • 1
    Well said, particularly 2. – Mardoxx Sep 27 '17 at 16:01
  • 1
    I know that this is very old thread, but I have to disagree with 1. You cannot make a method to abstract mapping. You can for 1 class, but if have 2, you need 2 methods. 3 - 3 methods. With AM this is 1 line of code - definition of mapping. Plus, I really struggled with a scenario, where I had a List<BaseType> filled with 10 subtypes DTO. When you want to map that, you need a switch on type AND a method to copy field values. And what if one of the fields has to be mapped seperately? Your answer is only good if you have few simple classes. AutoMapper wins hands down in more complex scenarios. – user3512524 Apr 12 '18 at 10:31
  • 1
    (char limit) The only pitfall of AM I think is the possibility of changing the name of property in one class and not in the other. But really, how often do you do that after the design is done? And you can write a generic test method that uses reflection and compares property names. Like all tools, AM has to be used correctly - not blindly, not in all situations, I agree. But saying "you should not use it" is just wrong. – user3512524 Apr 12 '18 at 10:36
7

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:

  1. Write some tedious, repetitive, mundane boilerplate along the lines of this.x = that.x; this.y = that.y
  2. Generate the code somehow.
  3. Use reflection.

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.

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.