Mapping code is boring. Testing mapping code is even more boring. AutoMapper provides simple configuration of types, as well as simple testing of mappings.

What Is AutoMapper?

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?

How To Use

Firstly, create a configuration for mapping.

​var config = new MapperConfiguration(cfg => 
    cfg.CreateMap<UserBM, UserDAL>()
);

This mean all property of object UserDAL will fill to all property of UserBM if their same name.

If 2 objects have difference properties' name or you need to configure before map data with ForMember, MapFrom.

​var config = new MapperConfiguration(cfg => 
    cfg.CreateMap<UserBM, UserDAL>()
    .ForMember(des => des.Password, opt => opt.MapFrom(src => src.Password.GetSha512Hash()))

    // Call UseValue for execute function => the function execute only one time
    // Just use UseValue for static, constant value
    .ForMember(des => des.CreateOnUtc, opt => opt.UseValue(DateTime.UtcNow)

    // This not make sense because the value of destination object not relate to source object
    .ForMember(des => des.LastUpdateOnUtc, opt => opt.MapFrom(src => DateTime.UtcNow)

    // You can put business logic and do everything after map in this block
    .AfterMap((src, des) => {
    	des.DeleteOnUtc = DateTime.UtcNow;
    });

MapFrom: you can do the logic map here with function.

UseValue: you can put static value for the destination property.

BeforeMap: do some logic before map executed.

AfterMap: do some logic after map executed.

* Note: In ForMember, if you use "UseValue" it will execute once when the mapper configuration build and put static value in there(AutoMapper do it for performance purpose), so in this example "CreateOnUtc" in runtime will give a wrong value.

For more clear, If the code configuration run in UTC is 12/12/2016 0:0:0, so when you call MAP function to map data for 2 objects the CreateOnUtc always 12/12/2016 0:0:0 not runtime value.

Solution to resolve this issue is if you want to use UseValue for some case like DateTime you can use AfterMap like the above code for "DeleteOnUtc", it provide to you can call your function, do business logic after map and it always run when MAP execute.

Or you can still use ForMember with MapFrom and function like the line of code for "LastUpdateOnUtc" but it does not make sense.

The another way to config mapper is you can put the configuration in a separate class to reuse.

​public class UserMap : Profile
{
    protected override void Configure()
    {
        CreateMap<UserBM, UserDAL>()
        .ForMember(des => des.Password, opt => opt.MapFrom(src => src.Password.GetSha512Hash()));
    }

    public UserDAL GetUserDAL(UserBM userBM)
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile<UserMap>();
        });

        var mapper = config.CreateMapper();

        return mapper.Map<UserBM, UserDAL>(userBM);
    }
}

See more

Secondly, you can map your objects in an easy way.

var mapper = config.CreateMapper();

// or
UserDAL userDAL = new Mapper(config).Map<UserDAL>(userBM);

// or
UserDAL userDAL = Mapper.Map<UserDAL>(userBM);

// or
​UserDAL userDAL = new UserMap().GetUserDAL(userBM);

You can check out the getting started guide.

See more example here.

Support for Entity Framework

You need to install an extension of AutoMapper to make AutoMaper working with Entity Framework 6

Then you can map objects into query statement

​Mapper.CreateMap<Employee, EmployeeDto>()
    .ForMember(d => d.FullName, opt => opt.MapFrom(src => src.FirstName + " " + src.LastName));

var employees = await db.Employees.ProjectTo<EmployeeDto>().ToListAsync();

Or

​public class Employee {
    [Computed]
    public string FullName { get { return $"{FirstName} {LastName}"; } }
}

Mapper.CreateMap<Employee, EmployeeDto>();

var employees = await db.Employees.ProjectToListAsync<EmployeeDto>();

This package wraps up calling ProjectTo, the DelegateDecompiler Decompile/DecompileAsync methods, and then the LINQ methods to execute the queryable (ToList, ToArray, Single, SingleOrDefault etc).

Test Configuration

​var config = AutoMapperConfiguration.Configure();

config.AssertConfigurationIsValid();

See more

An Important NuGet Note

Auto Mapper

​PM> Install-Package AutoMapper

Github link

Wiki link

Website link

Auto Mapper and EF 6

​PM> Install-Package AutoMapper.EF6

Github link

Summary

AutoMapper is an object-object mapper. Object-object mapping works by transforming an input object of one type into an output object of a different type. What makes AutoMapper interesting is that it provides some interesting conventions to take the dirty work out of figuring out how to map type A to type B. As long as type B follows AutoMapper's established convention, almost zero configuration is needed to map two types.

Happy Coding!