Monday, April 20, 2015

AutoMapper is evil

tl;dr Automapper kills traceability making software maintenance increasingly difficult. It's also a gateway drug to a bunch of anti-patterns.

I've turned from an AutoMapper advocate to a strong opponent over the course of about a year.

At first it seems like a great way to reduce stupid repetitive code. It accelerates initial development.

All is good and well until you have to change the application and all the nice tooling that helps us refactor with confidence breaks down because it cannot see the implicit coupling between mapped objects.

Compiler checks are gone.

Traceability is gone.

Debugging is next to impossible.

Profile validation to the rescue?

AutoMapper allows you to mitigate this to some extent by grouping mappings into profiles and then asserting that the profile is valid, meaning that all properties of the destination types are mapped.

This however requires that any unused properties in the destination type are ignored. If mappings address only a subset of fields on your types this will lead to lots of custom configuration code in your mappings, essentially defeating the main benefit of AutoMapper: less mapping code.

AutoMapper is not free

AutoMapper was hailed by some as the solution to ease the implementation of strictly layered architectures and later DDD. Decoupling layers or domains is impossible without mapping or transforming from one model to the next.

While AutoMapper can indeed help ease that burden, I'm inclined to agree with Greg Young that all this mapping is painful and if you really want to do this, you should feel that pain.(See 8 lines of code by Greg Young, skip to 39:00 for the bit about AutoMapper)

All that mapping magic does not come for free. Besides the maintenance issues mentioned earlier, AutoMapper also has a performance cost.

Setting up a lot of mappings is expensive as expressions need to be compiled on startup. Once that is done, AutoMapper is still nowhere near as fast as straight up hand written assignments.

Have a look at the performance comparison offered by AutoMapper alternative FastMapper (FastMapper on CodePlex, scroll all the way down for the performace comparison).

In an average application a bit of AutoMapper won't hurt, but once load increases it can definitely start to make a difference. A concrete case I saw was in a message driven application where large volumes of messages were being transferred during upgrades on deployment of new releases. Performance analysis showed that AutoMapper consumed between 10 and 20% of the CPU time. 

A final word

I have stopped using AutoMapper completely and have not regretted that once. Hand authored mapping code is faster, easier to understand and easier to maintain.

4 comments:

Jimmy Bogard said...

These days, I pretty much only use AutoMapper with the LINQ projections. That way it's the LINQ provider manipulating the underlying SQL and I generally avoid the in-memory mapping capabilities.

The nice thing about building around commands and queries is you can move away from these approaches if you like and do micro ORM instead.

SergeJack said...

Have you tried alternatives like FastMapper?

Marnix said...

No, I haven't. Not for production use anyway. I've moved on to happier projects ;)

The point of this post is mostly that I dislike the whole idea of using a lib to map data from one poco to another. It may be a solution for repetitive code but it comes with a serious proce tag in the long run. I understand that mapping cannot be avoided in certain cases but I would stronlgy reconsider the archtiecture that needs this kind of solution.

Anonymous said...

Just upgraded AutoMapper and got a world of pain as everything is now broken and the most basic functionality just doesn't work properly if all! Get a constant stream of stupid error messages - now spending a few hours stripping all that shite out!!