Mapping an Entity to EntityDto and vice versa using AutoMapper
In modern application development, it's common to separate data transfer objects (DTOs) from the actual entities that represent data in the database. This separation allows for a cleaner architecture, where DTOs handle data transfer between the client and server, and entities represent the domain model within the application. AutoMapper is a powerful library that simplifies the mapping between these objects. In this article, we’ll explore how to map an entity to a DTO and vice versa using AutoMapper in a .NET application.
What is AutoMapper?
AutoMapper is an object-to-object mapping library that helps in automating the mapping process between different object models. It eliminates the need for manual mapping code, reducing boilerplate code and potential errors.
https://docs.automapper.org/en/latest/Getting-started.html
Step 1: Setting Up AutoMapper
To get started, you need to install the AutoMapper and AutoMapper.Extensions.Microsoft.DependencyInjection packages via NuGet:
dotnet add package AutoMapper
dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection
Step 2: Setting Up AutoMapper
using BookStore.Contracts.AutoMapperProfiles;
using BookStore.EFCore;
using BookStore.Services;
using FastEndpoints;
using FastEndpoints.Swagger;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddFastEndpoints()
.SwaggerDocument();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var connectionString = builder.Configuration.GetConnectionString("Default");
builder.Services.AddApplicationContext(connectionString);
builder.Services.AddBookStoreServices();
//Add this
builder.Services.AddAutoMapper(typeof(BookProfile));
var app = builder.Build();
app.UseFastEndpoints(c =>
{
c.Endpoints.RoutePrefix = "api";
}).UseSwaggerGen();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.Run();
using AutoMapper;
using AutoMapper;
using BookStore.Contracts.Books;
using BookStore.Domain;
namespace BookStore.Contracts.AutoMapperProfiles;
public sealed class BookProfile : Profile
{
public BookProfile()
{
CreateMap<Book, BookDto>();
CreateMap<BookDto, Book>();
CreateMap<CreateBookInputDto, Book>();
}
}
Step 3: Updating the services
Since we have only one service at the moment, we will only update BookService
using AutoMapper;
using BookStore.Contracts.Books;
using BookStore.Domain;
using BookStore.EFCore.Repositories;
namespace BookStore.Services.Services;
public class BookService(IBookRepository bookRepository, IMapper mapper) : IBookService
{
public async Task<List<BookDto>> GetAll(int skip =0, int take=0, CancellationToken ctx = default)
{
var data = await bookRepository.GetAll(skip, take,ctx);
return mapper.Map<List<BookDto>>(data);
}
public async Task<BookDto?> GetById(int bookId, CancellationToken ctx = default)
{
var book = await bookRepository.GetById(bookId, ctx);
return book is null ? null : mapper.Map<BookDto>(book);
}
public async Task<BookDto?> CreateBook(CreateBookInputDto input, CancellationToken ctx = default)
{
var book = mapper.Map<CreateBookInputDto, Book>(input);
await bookRepository.AddBook(book, ctx);
return mapper.Map<BookDto>(book);
}
}
Conclusion
AutoMapper significantly simplifies the process of mapping between different object models in a .NET application. By setting up a mapping profile and configuring AutoMapper in your application, you can easily convert entities to DTOs and vice versa, making your code cleaner and more maintainable. This approach helps in adhering to the single responsibility principle and keeps your application architecture well-organized.
Subscribe to my newsletter
Read articles from Khalil directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by