Automapper consente di creare un meccanismo di mappatura tra classi. Tipicamente viene utilizzato per la mappatura tra DTO e la business logic dell’applicazione.
Automapper può essere facilmente integrato all’interno di applicazioni .NET Core, installando i pacchetti:
- Automapper
- AutoMapper.Extensions.Microsoft.DependencyInjection
con i comandi:
dotnet add package AutoMapper dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection
Il primo pacchetto è il core di Automapper, mentre il secondo consente di gestire la dependency injection all’interno della nostra applicazione.
Una volta installato, all’interno di Program.cs può essere facilmente integrato registrandono all’interno dei services:
builder.Services.AddAutoMapper(....)
passando opportuamente la configurazione da utilizzare.
L’organizzazione della configurazione può essere fatta utilizzando un oggetto MapperConfiguration:
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<TSource, TDestination>()
);all’interno del quale vengono definire le regole di mapping tra TSource e TDestination.
Sicuramente questo tipo di configurazione può essere utilizzata all’interno di applicazioni non molte grandi, ma al crescere delle dimensioni aumenta anche la complessità della gestione delle mappature.
Automapper consente di gestire la configurazione della mappatura utilizzando il meccanismo del Profile. In pratica è possibile utilizzare una classe che eredita direttamente da Profile e definire al suo interno la configurazione della mappatura.
In questo modo è possibile creare un file per ogni mappatura, creando una struttura facilmente mantenibile ed utilizzabile. La condizione ottimale sarebbe quella di avere a disposizione un meccanismo che consenta di caricare in maniera dinamica le configurazioni, senza dover utilizzare una registrazione manuale.
public class UserProfile : Profile
{
public UserProfile()
{
CreateMap<UserDto, User>()
.ForMember(
dest => dest.FirstName,
opt => opt.MapFrom(src => $"{src.FirstName}")
)
.ForMember(
dest => dest.LastName,
opt => opt.MapFrom(src => $"{src.LastName}")
)
.ForMember(
dest => dest.Email,
opt => opt.MapFrom(src => $"{src.Email}")
)
.ForMember(
dest => Convert.ToDateTime(dest.DateOfBirth),
opt => opt.MapFrom(src => $"{src.DateOfBirth}")
)
.ForMember(
dest => dest.Phone,
opt => opt.MapFrom(src => $"{src.Phone}")
)
.ForMember(
dest => dest.Country,
opt => opt.MapFrom(src => $"{src.Country}")
)
.ForMember(
dest => dest.Status,
opt => opt.MapFrom(src => 1)
);
}
}Nell’esempio viene definita la mappatura tra UserDTO e User, indicatndo anche le regole di mappatura dei singoli campi. Da notare che la classe UserProfile eredita da Profile proprio per poter essere utilizzata come configurazione da Automapper.
La mappatura viene effettuata all’interno del costruttore.
Il meccanismo di caricamento automatico, utilizza l’assembly del progetto che stiamo utilizzando. In particolare, all’interno di Program.cs possiamo utilizzare:
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
In questo modo la configurazione viene caricata direttamente a partire da:
AppDomain.CurrentDomain.GetAssemblies()
che consente la scansione e la lettura di tutte le configurazioni di mapping che sono state definite.