En C# (.NET), DTO signifie Data Transfer Object.
Un DTO est un objet utilisé pour transférer des données entre différentes couches d'une application, par exemple entre la couche de service et la couche de présentation. Les DTO sont généralement des objets simples qui contiennent uniquement des propriétés et ne possèdent pas de logique métier.
Pourquoi utiliser des DTO ?
- Performance : Réduire la quantité de données transférées en sélectionnant uniquement les champs nécessaires.
- Sécurité : Éviter d'exposer directement les entités de la base de données.
- Simplicité : Faciliter la sérialisation et le transfert de données via des API ou des services.
- Découplage : Isoler les modèles de domaine des modèles d'affichage ou d'API.
Exemple de DTO en C#
public class UserDto
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
Exemple d'utilisation
Supposons que vous ayez une entité utilisateur dans votre base de données, mais que vous ne souhaitiez exposer que certains champs :
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string PasswordHash { get; set; }
public DateTime CreatedAt { get; set; }
}
Pour transférer les données à travers une API sans exposer les informations sensibles comme le mot de passe, vous pouvez mapper l'entité vers un DTO :
UserDto dto = new UserDto
{
Id = user.Id,
Username = user.Username,
Email = user.Email
};
En résumé, les DTO sont très utiles pour transférer des données de manière sécurisée et efficace, en isolant les modèles de domaine des modèles d'affichage ou d'API.
AutoMapper est une bibliothèque .NET qui permet de mapper automatiquement des objets entre eux, généralement entre des objets de domaine (modèles d'entités) et des objets de transfert de données (DTO).
Elle est particulièrement utile pour éviter d'écrire du code répétitif lors de la conversion entre différents objets.
🔧 Installation
Pour installer AutoMapper via NuGet, utilisez cette commande :
dotnet add package AutoMapper
dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection
💡 Comment ça marche ?
AutoMapper utilise des profils pour configurer les mappages entre différents objets.
🔥 Exemple simple
1. Modèles (Domain Model et DTO)
public class User
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
}
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
2. Configuration de AutoMapper (Profile)
AutoMapper utilise les Profiles pour définir les mappages.
using AutoMapper;
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<User, UserDto>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName));
}
}
3. Configuration dans un projet .NET (Program.cs ou Startup.cs)
using AutoMapper;
var builder = WebApplication.CreateBuilder(args);
// Ajouter AutoMapper au conteneur de services
builder.Services.AddAutoMapper(typeof(UserProfile));
var app = builder.Build();
app.Run();
4. Utilisation dans un service ou un contrôleur
using AutoMapper;
public class UserService
{
private readonly IMapper _mapper;
public UserService(IMapper mapper)
{
_mapper = mapper;
}
public UserDto GetUserDto(User user)
{
return _mapper.Map<UserDto>(user);
}
}
5. Appel du service
var user = new User { Id = 1, FullName = "John Doe", Email = "Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser. " };
var service = new UserService(new MapperConfiguration(cfg => cfg.AddProfile<UserProfile>()).CreateMapper());
UserDto dto = service.GetUserDto(user);
Console.WriteLine($"DTO: {dto.Id}, {dto.Name}, {dto.Email}");
🌟 Avantages d'AutoMapper
- Productivité : Réduit la quantité de code boilerplate.
- Maintenance : Les mappings sont centralisés, ce qui simplifie la maintenance.
- Performances : Les mappages sont précompilés, ce qui améliore les performances.
- Flexibilité : Permet de configurer des règles de mapping complexes.
🔄 Mapping bidirectionnel
AutoMapper permet aussi de faire des mappings dans les deux sens :
CreateMap<User, UserDto>().ReverseMap();
🪄 Mapping avec transformation
Vous pouvez également transformer les données pendant le mapping :
CreateMap<User, UserDto>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName.ToUpper()));
AutoMapper est donc un excellent outil pour simplifier la conversion entre objets, notamment dans les applications qui utilisent beaucoup de DTOs.
🌟Mapping avec transformation
Détaillons la syntaxe d'AutoMapper étape par étape, en simplifiant les concepts !
💡 Les bases d'AutoMapper
AutoMapper utilise un concept de profil pour définir les règles de transformation entre deux objets.
Un profil est comme un plan qui dit à AutoMapper comment copier les données d'un objet source vers un objet de destination.
📌 Étape 1 : Créer les classes (Model et DTO)
Imaginons que nous ayons un modèle d'utilisateur et un DTO (Data Transfer Object).
Classe User
(Modèle de domaine)
public class User
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
}
Classe UserDto
(DTO)
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
📌 Étape 2 : Créer un profil de mappage
On utilise une classe qui hérite de Profile
pour configurer les mappages.
Classe UserProfile
using AutoMapper;
public class UserProfile : Profile
{
public UserProfile()
{
// Créer un mappage de User vers UserDto
CreateMap<User, UserDto>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName));
}
}
🔍 Explications sur la syntaxe
-
CreateMap<User, UserDto>()
→ Crée un lien de mappage entre la classeUser
et la classeUserDto
. -
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.FullName))
→ Indique que la propriétéName
de l'objetUserDto
doit être remplie avec la valeur de la propriétéFullName
de l'objetUser
.
📌 Étape 3 : Configurer AutoMapper (dans Program.cs
ou Startup.cs
)
Pour que le mappage fonctionne dans toute l'application, il faut enregistrer AutoMapper dans le conteneur de services.
Program.cs
using AutoMapper;
var builder = WebApplication.CreateBuilder(args);
// Ajouter AutoMapper au conteneur de services
builder.Services.AddAutoMapper(typeof(UserProfile));
var app = builder.Build();
app.Run();
📌 Étape 4 : Utiliser AutoMapper
Dans un service ou un contrôleur, vous allez injecter IMapper
pour effectuer la conversion.
UserService.cs
using AutoMapper;
public class UserService
{
private readonly IMapper _mapper;
public UserService(IMapper mapper)
{
_mapper = mapper;
}
public UserDto GetUserDto(User user)
{
// Utiliser AutoMapper pour convertir un User en UserDto
return _mapper.Map<UserDto>(user);
}
}
📌 Étape 5 : Appeler le service
var user = new User { Id = 1, FullName = "John Doe", Email = "Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser. " };
var mapper = new MapperConfiguration(cfg => cfg.AddProfile<UserProfile>()).CreateMapper();
var service = new UserService(mapper);
UserDto dto = service.GetUserDto(user);
Console.WriteLine($"DTO: {dto.Id}, {dto.Name}, {dto.Email}");
📝 Résultat
Le programme va afficher :
DTO: 1, John Doe, Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.
🚀 Pourquoi utiliser AutoMapper ?
- Simplicité : Moins de code répétitif.
- Performance : Le mappage est précompilé, donc plus rapide que les mappings manuels.
- Centralisation : Tous les mappages sont définis en un seul endroit.