CleanArch.DevKit.Mapping
1.1.1
dotnet add package CleanArch.DevKit.Mapping --version 1.1.1
NuGet\Install-Package CleanArch.DevKit.Mapping -Version 1.1.1
<PackageReference Include="CleanArch.DevKit.Mapping" Version="1.1.1" />
<PackageVersion Include="CleanArch.DevKit.Mapping" Version="1.1.1" />
<PackageReference Include="CleanArch.DevKit.Mapping" />
paket add CleanArch.DevKit.Mapping --version 1.1.1
#r "nuget: CleanArch.DevKit.Mapping, 1.1.1"
#:package CleanArch.DevKit.Mapping@1.1.1
#addin nuget:?package=CleanArch.DevKit.Mapping&version=1.1.1
#tool nuget:?package=CleanArch.DevKit.Mapping&version=1.1.1
CleanArch.DevKit.Mapping
Mappers d'objets générés à la compilation. Pas de réflexion, pas d'AutoMapper, pas de configuration runtime.
Rôle
Permet de déclarer un mapper entre deux types via une classe partial décorée d'un attribut [Mapper<TFrom, TTo>]. Le générateur Roslyn analyse les propriétés source et destination par nom, émet le corps de la méthode Map, et inscrit un dispatcher IMapper global dans le conteneur DI.
Installation
dotnet add package CleanArch.DevKit.Mapping
Le générateur Roslyn est embarqué dans le package.
Fonctionnalités
- Déclarer un mapper avec
[Mapper<TFrom, TTo>] - Mapping conventionnel par nom de propriété
- Override de propriété via méthode
Map<PropertyName> - Mapping vers record positionnel ou type avec init-only
- Dispatcher centralisé
IMapper - Enregistrement DI via
AddMappers()(généré) - Diagnostics Roslyn (
MAP001–MAP003)
Déclarer un mapper
Le mapper est une partial class décorée et qui déclare la signature de Map :
public sealed record User(int Id, string Email, string Name);
public sealed record UserDto(int Id, string Email, string Name);
[Mapper<User, UserDto>]
public partial class UserMapper
{
public partial UserDto Map(User source);
}
Le générateur émet le corps de Map en associant les propriétés par nom.
Mapping conventionnel par nom
Le générateur cherche, pour chaque propriété de destination, une propriété source du même nom. Le mapping fonctionne avec :
- les types
record(constructeur positionnel) - les classes avec init-only setters
- une combinaison ctor positionnel + init properties
public sealed record OrderDto(Guid Id, decimal Total)
{
public string Currency { get; init; } = "EUR";
}
[Mapper<Order, OrderDto>]
public partial class OrderMapper
{
public partial OrderDto Map(Order source);
}
Id et Total passent par le constructeur, Currency par init-only.
Override d'une propriété
Quand le mapping conventionnel ne peut pas s'appliquer (types différents, transformation custom), déclarer une méthode statique Map<NomDeLaPropriété> sur la classe partielle :
public sealed record UserId(Guid Value)
{
public override string ToString() => Value.ToString("N")[..8];
}
public sealed record User(UserId Id, string Email);
public sealed record UserDto(string Id, string Email);
[Mapper<User, UserDto>]
public partial class UserMapper
{
public partial UserDto Map(User source);
// Le générateur appelle MapId(source) pour la propriété Id
private static string MapId(User source) => source.Id.ToString();
}
Le générateur reconnaît Map<PropertyName>(TFrom source) et l'utilise au lieu de la convention par nom.
Enregistrer les mappers
AddMappers() est généré : il inscrit chaque mapper en singleton et un dispatcher IMapper qui route par (type source runtime, type destination) :
services.AddMappers(); // émis par le générateur
Côté consommateur, deux façons d'invoquer :
// Via le dispatcher agrégé — pratique quand on ne veut pas dépendre du mapper concret
var dto = mapper.Map<UserDto>(user);
// Directement via le mapper concret — typé, sans boxing
var dto = userMapper.Map(user);
IMapper.Map<TDestination>(object) lève MappingNotFoundException si aucun mapper n'est inscrit pour la paire (typeof(source), TDestination).
Diagnostics à la compilation
| Code | Sévérité | Condition |
|---|---|---|
MAP001 |
Error | Une propriété destination n'a ni source de même nom ni méthode MapXxx |
MAP002 |
Error | La classe [Mapper] n'est pas déclarée partial |
MAP003 |
Error | La signature public partial TTo Map(TFrom source) est absente |
Ces erreurs apparaissent dans le build : impossible d'obtenir un mapper incomplet ou mal câblé au runtime.
Plusieurs mappers sur une même classe
[Mapper<,>] est AllowMultiple = true. Une même classe partielle peut donc regrouper plusieurs mappings (tant que les types source diffèrent — C# n'autorise pas la surcharge par seul type de retour) :
[Mapper<User, UserDto>]
[Mapper<Address, AddressDto>]
public partial class Mappers
{
public partial UserDto Map(User source);
public partial AddressDto Map(Address source);
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.1 | 86 | 5/17/2026 |
| 1.1.0 | 87 | 5/17/2026 |
| 1.0.0 | 84 | 5/15/2026 |
| 0.1.0-preview.1 | 46 | 5/14/2026 |