ADR 0003 — Mapper reflection custom en complément d'AutoMapper
Date : initial Statut : Accepté
Contexte
Le projet utilise déjà AutoMapper 13 avec un Profile unique (Application/Profiles/Profiles.cs). Beaucoup d'entités font un round-trip simple Entity ↔ DTO sans transformation (mêmes noms de propriétés, types compatibles). Définir un CreateMap<X, Y>().ReverseMap() pour chaque DTO double la verbosité du Profile.
Décision
Maintenir AutoMapper pour les mappings avec règles explicites (calculs, formatage, projection partielle), mais utiliser un mapper reflection custom (Application/Library/Mapper.cs) pour les round-trips simples.
API du mapper custom :
var dto = Mapper<EntityDto, Entity>.Map(new EntityDto(), entity);
var entity = Mapper<Entity, EntityDto>.Map(new Entity(), dto);Convention : la destination est le 1er paramètre (instance), la source est le 2e.
Utilisé notamment dans BookingService pour Passenger ↔ BookingPassengerDto et dans plusieurs services CRUD légers.
Conséquences
- ✅ Pas besoin d'écrire un Profile pour les DTOs symétriques.
- ✅ Tolérant aux ajouts de propriétés : un nouveau champ commun (même nom + type) est mappé automatiquement.
- ❌ Aucune validation à la compilation : un typo dans un nom de propriété passe silencieusement.
- ❌ Reflection ⇒ moins performant qu'AutoMapper (qui compile l'expression). Non critique aux volumes Horizon.
- ❌ Le développeur doit savoir lequel utiliser. La règle : AutoMapper si transformation, Mapper custom si miroir simple.
Pièges connus
- Les types
Guid?↔Guidpeuvent ne pas se mapper proprement selon l'implémentation. Vérifier le code deLibrary/Mapper.csavant d'utiliser. - Les collections imbriquées peuvent ne PAS être recopiées en profondeur. À vérifier pour chaque cas d'usage.

