2.5 KiB
0008. Use AutoMapper for DTO Mapping
Date: 2026-04-02
Status
Accepted
Context
The API separates its public contract (request/response DTOs) from its internal persistence model (Player entity). Every controller action that reads or writes data must map between these representations. Without a mapping library, this means writing explicit property-assignment code (responseModel.Name = entity.Name, etc.) in every service method — boilerplate that grows linearly with the number of fields and operations.
AutoMapper provides convention-based mapping: if property names match between source and destination, the mapping is configured once in a profile and applied everywhere. Custom mappings (renaming, transforming, ignoring fields) are expressed declaratively in the profile class.
Decision
We will use AutoMapper for all DTO-to-entity and entity-to-DTO mappings. Mappings are defined in PlayerMappingProfile under Mappings/ and registered via AddAutoMapper(typeof(PlayerMappingProfile)). PlayerRequestModel does not expose an Id property, so callers structurally cannot set or override the internal primary key — no explicit .ForMember(...Ignore()) is required on the PlayerRequestModel → Player mapping. The Player → PlayerResponseModel mapping suppresses the AutoMapper validation warning for the unmapped Id source member via .ForSourceMember(source => source.Id, options => options.DoNotValidate()).
Consequences
Positive
- Eliminates repetitive property-assignment boilerplate in service methods.
- Mapping configuration is centralised in one profile class, making it easy to audit what is and is not mapped.
- Protection of the internal
Idis structural — the absence ofIdonPlayerRequestModelis the guarantee, which is simpler and more robust than relying on an explicit ignore rule.
Negative
- AutoMapper uses reflection at startup to validate mapping configurations, adding a small startup overhead.
- "Magic" convention-based mapping can be opaque: when a property is silently unmapped due to a name mismatch, the bug only surfaces at runtime (though
AssertConfigurationIsValid()in tests can catch this). - Adding AutoMapper as a dependency means contributors must understand profile configuration to modify or extend mappings.
Neutral
- AutoMapper's
ProjectTo<T>()LINQ extension for EF Core queryable projections is available but not currently used. Direct entity retrieval followed by in-memory mapping is sufficient at this project's scale.