What is AutoMapper? Why should we use it?

What is AutoMapper? Why should we use it?


AutoMapper is an object-object mapper. Object-object mapping works by converting an input object of one type into a different type of output object. What makes AutoMapper usable is that it provides some interesting rules for eliminating their dirty work by figuring out how to match the type A model to the type B model.

AutoMapper Documentation

Let's take two models to sit in your mind.

class Foo{
	public int baz;
	public string name;
	public string lastName;
}

class Bar {
	public uint baz;
	public string name;
	public string surName;
}

Here, when you use AutoMapper, you can cast Foo and Bar models to a different model by matching in a single line without matching a single property. The beauty of AutoMapper is that you can run the same mapping code blocks everywhere with a one-off configuration. Based on the example above, if you write code in one place by simply taking the lastName property in the AutoMapper Foo model and writing it to the surName property of the Bar model, this will be automatically applied to your entire project. Is not it beautiful!

Let's do a few examples of how to do it.

Nuget

PM> Install-Package AutoMapper

Let's introduce AutoMapper to our project.

Now let's enter Startup.cs and write the following code in ConfigureServices.

services.AddAutoMapper(typeof(Startup));

Now we create the config file for which models it will do this. Creating a class that takes the Profile class as a base and the operations that I do in its ctor will be recognized by AutoMapper and will be taken into account in casting operations. Double-sided conversion is configured for the Tag below. As a result of this configuration, the values of the same properties will be automatically mapped to the other model. If you have different properties in Foo and Bar, you can also extend them using ForMember.

public class MappingProfile : Profile
{
    public MappingProfile()
    {
        CreateMap<TagEntity, TagViewModel>();
        CreateMap<TagViewModel, TagEntity>();

        CreateMap<Foo, Bar>()
            .ForMember(dest => dest.lastName,
                opt =>
                    opt.MapFrom(src => src.surName)
            );

        CreateMap<Bar, Foo>()
            .ForMember(dest => dest.surName,
                opt =>
                    opt.MapFrom(src => src.lastName)
            );
    }
}

All the above operations were configurable. Let's give an example for this process.

public class TagController : Controller
{
    private readonly IMapper _mapper;

    public TagController(IMapper mapper)
    {
        _mapper = mapper;
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(TagViewModel model)
    {
        var entity = _mapper.Map<TagEntity>(model);
        // TODO
        return RedirectToAction("Edit", "Tag", new {entity.Id});
    }

    public async Task<IActionResult> Edit(int id)
    {
        var entity = await db.Tags.FirstOrDefaultAsync(_ => _.Id == id);
        var model = _mapper.Map<TagViewModel>(entity);
        return View(model);
    }
}

As you can see, we have easily mapped all the models in a few lines. Imagine doing this throughout the project and feel the comfort of being able to easily apply a change like the Foo Bar example anywhere on a single page.

I wish you less, fast and stress-free working life...

An error has occurred. This application may no longer respond until reloaded. Reload 🗙