AutoMapper considered harmful
If I were to briefly describe the software development, I would say that we essentially just take data in one place, transform (map) it to another shape and send to a different place. In other words, the whole development process is mapping.
In some cases we try to simplify the process of mapping and there are a few ways to do that. One of the options is to use a special library.
I have been doing C# for many years and as my friends (most of them are C# developers) used AutoMapper in my projects. I believe it was and is the most popular library for mapping objects.
The main advantage of AutoMapper is the economy of time spent or writing mapping code. If two objects have the same field name, the field will be automatically mapped with the help of reflection.
Lately I had yet another debate with my friend about the pros and cons of AutoMapper and I would like to share my thoughts up here.
Disclaimer: I don’t use AutoMapper since I don’t use C# anymore and in F# there is no need for it anyway. I also have to mention that the concerns below are related to any similar mapping library, not only AutoMapper itself.
Poor code navigation experience
If your objects are mapped with default Automapper config, you cannot find where a field takes its value. Even if you use good tooling (VS, Rider) and try to “Find usages” you won’t be able to find neither assignment nor usage. This is especially bad for developers new to project.
Refactoring issues
At some point you might want to rename a field in one of the models. If you do that, the compiler won’t complain of anything and you will find the issue at runtime, sometime, maybe… Since there is no usage of field in the code for mapping, you might have a really bad debugging. Similar problem can appear with nullable types. But in C# it is still not the easiest thing to solve, especially on older projects. That’s where F# with its static typing and the lack of implicits shines. Should you change a field type to `Option<T>`, you get a compilation error. And then if it compiles, it works :)
Domain Driven Development
As I mentioned above, the main advantage of AutoMapper is that it saves time spent on writing the mapping code. I got this question: “Do you really write mapping code for all 50+ fields of a type?” And the answer is simple. If you have to do that and your fields have exactly the same names, you are probably doing something wrong. Usually that comes from some storage (a DB). But that means you are doing Data driven development. If you start modeling your types based on domain regardless of how the data should be stored you will most likely have different names of fields and smaller objects.
Anyway, even if you need to write that much mapping code, remember, it is not the bottleneck of development speed. You will save much more time on maintaining and refactoring the code later on.
Mapping validation
AutoMapper provides a method for validating the mapping configuration in tests. You can run tests to make sure all your mapping configurations are valid. But this, again, is the same comparison between “dynamic” typing and the need to write more tests and the static typing, which is checked by compiler and eliminates the necessity to write type checking tests. Also the compiler is usually used by the IDE and provides you with errors in real time, even before the compilation.
To summarize
I strongly discourage you from using Automapper or similar libraries. Write the code you can reason about and take responsibility for.