When it comes to passing business object to and from business layer, in my consultancy I’ve seen, roughly speaking, the following two approaches:
- Business entities get directly passed from and to business layer.
- Data transfer objects (DTOs) get passed from and to business layer.
Explaining the issues coming from the first approach would require a blog post of its own and is not the topic of this article. The second approach is, at least in my part of the programming universe, the prevailing one.
The second approach brings the question of mapping the DTOs to the business entities and vice versa. Here is the summary of the approaches I’ve witnessed:
- AutoMapper is used directly, without wrapping it behind a proprietary mapping abstraction.
- A self-made reflection-based mapping framework is used, often similar to this one.
- Manually written mappings are used. They reside in either static or non-static classes, sometimes extension methods. Classes sometimes implement proprietary mapping interfaces.
- A proprietary mapping abstraction is used, in terms of mapping interfaces. The standard implementations are provided by AutoMapper. Complex mappings are implemented manually.
The second approach, self-made mapping frameworks, is rare to see in new solutions and it brings no advantages compared to AutoMapper. Not to mention that is most likely oversimplified and error-prone, just as the example linked above.
AutoMapper is by far, again, in my consulting experience, the most popular approach. It offers plenty of benefits, but, as every magical technology, it has its drawbacks.
Cezary Piątek explained these drawbacks in his article titled “The reasons behind why I don’t use AutoMapper.” The article gain traction in the community including a very constructive feedback and opinion by Jimmy Bogard, the author of AutoMapper.
No matter if you use AutoMapper or not, I encourage you to read the article. To summarize the article in one line, I’ll quote one of the comments:
AutoMapper is a tool; like any tool, it’s not applicable to everything.
I’ve experienced some of the drawbacks presented in the article, especially the one of complex mapping being defined in AutoMapper rather than in code. Next to that one is the issue of blindly combining auto-mappings with ORMs, well described in Roger Johansson’s article provokingly titled “Why mapping DTOs to entities using AutoMapper and EntityFramework is horrible.” Here I perfectly agree with the author’s statement:
The design described in this post prevents you from doing Domain Driven Design, it is 100% impossible to use DDD if you are patching state directly into your entities from an DTO.
You are simply throwing state around w/o any safety net, your entities can go into all sorts of invalid states.
In his article Cezary advocated the use of manually written mappings admitting the fact that they are tedious to write and essentially can be seen as boilerplate code. To address that issue, three weeks after publishing the article, he created Mapping Generator, a Visual Studio Extension for generating the mapping code at design time.
Mapping Generator obviously hit the spot. At the moment of writing it has 520 stars on GitHub and 7,300 installs on the Visual Studio Marketplace. And the comments like these testify that the tool proved to be very useful 🙂
In case you experienced drawbacks of AutoMapper and you are considering manual mappings as an alternative, or if you already write mappings on your own, I suggest you to give Mapping Generator a try.
As the name says, Mapping Generator will generate you mapping code for you. No matter what kind of proprietary mapping infrastructure you have in place and no matter how complex you DTOs and entities are, Mapping Generator will very likely get you covered.
The generator is implemented as a Roslyn code fix. It is an impressive example of what kind of tooling can be created with Roslyn. This was the reason why I listed Mapping Generator on the Awesome Roslyn list.
The best way to understand it is to see it in action. The “Main Features” chapter in the Mapping Generator README file contains animated gifs for numerous real-life use cases like pure mapping methods, updating methods, mapping constructors, and many other. To whet your appetite, here are some examples:
The code generation happens at design time, in the IDE. Mapping Generator supports all the major C# IDEs: Visual Studio, Rider, and Visual Studio Code. At design time means that you as a developer have to trigger the mapping generation manually. In the case you are looking for a more “auto” like experience, Cezary has provided an add-on that does it. You can read more about it in his article titled “How to simulate AutoMapper that works during the build time”.
AutoMapper is a useful and widely used library. If you use it already and experience only the benefits, keep using it. If you, on the contrary, already tend to write mappings on your own, or consider to start doing it, give Mapping Generator a try. You might end up being as grateful and thrilled as the three users quoted above 😉 In that case, do not forget to buy Cezary a coffee. He definitely deserves it!