AutoMapper and DTO

There are times developer need to implement something boring to make application easier to maintain. Fortunately there are millions of people that have the same problem and already developed solution. One of the worst thing to do is mapping one object to another, but it’s not a problem because we have AutoMapper. Additionally we’ll talk about great place to use our new knowledge, introducing DTO.

Data Transfer Object

DTO as you may deduce from name is class used to transfer data. It’s mostly used to transfer data from one layer to another. For example in WebAPI client will use DTO to send information to our API. Then we can map DTO to business model and start process. In short DTO is copy of business model, but contains only fields that user may access, so it’s limited business model.

Additionally it’s used only in between two layers, in this example DTO can’t go out of controller “layer”. Client side and controller are two layers. We need to map DTO to business model and then send it further. It is because we want to isolate passed models, thanks to that user won’t need to change his application whenever we change something in business model, unless we want to let him use new property. Still it will be decision made by developer instead of side effect.

Main reason to use DTO is to simplify transport of data. Business models are often pretty complex, so it better to have simple model for data transfer. It will make your code easier to maintain. Additionally it’s kind of contract. Two layers agrees to have common model, so it’s possible for two different teams to work independently. Finally when you use business model to transport data you’re at risk of exposing vulnerable data to another layer. It’s not that big deal if it’s inside of your project, but gets worse if you’re collaborating with another team or even company. You’ll have to hack thru life and hide somehow data that they shouldn’t access.

The biggest flaw of using DTO is that, it looks like waste of time at the beginning, because at start DTO and Domain Model looks the same, but it’ll be different sooner or later. Sometimes it’s too late to start creating DTOs, because it would cost too much to change everything else.

AutoMapper

Now that we covered why it’s good idea to use DTO, let’s find out what the best approach to make our work easier. As I said before writing mappers etc. is one of the worst thing to do, it’s boring, it takes time, and what the most important it’s easy to make a mistake. Fortunately we have AutoMapper, which will do exactly that. Create mappers automatically, or at least make it easier to create mappers.

Setup

It’s super easy, first you need to install nuget package. AutoMapper.Extensions.Microsoft.DependencyInjection.
Then you need to create mapping profile.
And finally register AutoMapper in DI container. You can do that easily using:
services.AddAutoMapper(typeof(StudentMapping).GetTypeInfo().Assembly); As parameter you need to specify assembly of project where you keep profiles. AutoMapper will scan in there and load all of profiles.

Here come the best thing about AutoMapper. The simplest profile will look like this:

public class StudentMapping: Profile
{
    public StudentMapping()
    {
       CreateMap<Core.Entities.Student, StudentResponse>();
       CreateMap<UpdateStudentRequest, Core.Entities.Student>();
       CreateMap<CreateStudentRequest, Core.Entities.Student>();
    }
}

AutoMapper can map matching properties based on name using reflection, before your red alert start beeping, it won’t affect performance, because AutoMapper will create profile for itself using reflection, then will use this profile to map objects.

Additional thing, models don’t have to be the same. AutoMapper will map what it can, it’s important to make sure that destination can be mapped fully. AutoMapper will validate by default that every property from destination is mapped. You can use additional options to change it. Using MemberList.Source will validate if every source property is mapped etc.

Usage

Now you can use it in your controllers etc. You need to inject IMapper, it will be used to map objects. Code to map one type to another is simple. It will look like this var student = mapper.Map(request); in this example mapper is injected by Autofac IMapper interface.

More information

For more information please check documentation, AutoMapper has one of the best documentation and it would be waste of time to copy it here. I’ll write later about additional use cases and things that needed more research than just reading documentation. In near future I’ll show you how to write unit tests for mappers, how to map multiple types into one and cool feature for Entity Framework which will make your code cleaner than ever

Leave a Reply