A few words about mappers in the programming world

In the .NET ecosystem there are many great mappers: Maperly, AutoMapper, Mapster, TinyMapper — yet with age I've come to realize it's better if we don't use them at all. I understand Junior Developers who are just discovering the world and want to pack as much as possible into their CV. I understand their enthusiasm with every new tutorial, where they learn the capabilities of a new tool that's supposed to do the work for them or let them shine among their colleagues.

Over time, however, I've come to realize that their absence neither slows down the development process nor brings any other drawbacks. With every additional library we use, we build a dependency. And that's the crux of the matter. Our code should be as small as possible with as few dependencies as possible, so that in the future we don't have to worry about what will happen if the tool's author decides to switch to a paid license, or simply stops supporting their own project — not to mention the increasingly common hacks on developers' accounts and the injection of malicious code into popular libraries.

We can think of it this way: we want code that, forgotten and rediscovered after many years, will still do its job. There will be no issues building the package. We won't worry about whether some library "A" or "B" is still available. After a longer period of a frozen project, we don't want to be forced to rewrite mappings while stressing that something will go wrong.

Unfortunately, people either forget that tests need to be written, or simply don't want to do it. And "magic" mapping is easy to break. What then? Not every time will testers run regression on all functionality. Not every bug gets caught, and a missing field can unfortunately be critical.

But I'm not worried. There's a solution. It's not spectacular. It's not some extraordinary technology from an alien civilization. The rescue comes in the form of the most ordinary thing: constructors. That's it. No more, no less. You won't need anything else. Just make sure your classes aren't anemic, that you don't give everyone the ability to change every field at any moment. Use records wherever you can. Try to use Value Objects as much as possible — and everything will be fine.

In the projects I work on today, I don't give the green light to creating classes that have no constructor (i.e., only the default one). The only exception — for convenience — is at application entry points, such as API input. Everywhere else, I'll block the MR. It's a certain kind of rigor, but it brings stability. Enforcing this approach, combined with the absence of external mapping libraries, produces predictability. You can't accidentally rename a variable and have the entire application stop working.

A final word for those who think this approach is too slow: learn your IDE!

Get to know the tools you use. If all you can do is Ctrl+C/V and Ctrl+T (double Shift), then I have a challenge for you: unplug your mouse and work with your IDE for a few hours. This will force you to learn new shortcuts and type faster.