When Automapper Is Not 'Auto'

February 20, 2017

When mapping between two different objects, like domain objects and DTOs, Automapper is one of the tools you can use. In theory, Automapper saves developers time and code by “auto” mapping objects they specify. Without Automapper, developers would have to create logic to map every property of their objects together.

Automapper works great when the properties of the mapped objects have identical names and types. However, what happens when the mapped object’s properties don’t have the same names/types or they even have a different number of properties?

When Automapper will not automatically map your objects, there are a few things we can do. The three most frequently used ways of configuring your maps are:

1) Ignore()

Ignore() can be used when you need to completely ignore a property in the mapping. The ignored property could be in either the source or the destination object. For example, if you don’t want to share the object's Id with the DTO object, you could use Ignore() to leave it out of the mapping:

public void BuildPublicMap(IMapperConfigurationExpression config)
{
    config.CreateMap<domainObject, dto>()
        .ForSourceMember(src => src.Id, opts => opts.Ignore());
}

When you go back from the DTO to the domain object, you would use Ignore() again:

public void BuildPublicMap(IMapperConfigurationExpression config)
{
    config.CreateMap<dto, domainObject>()
        .ForMember(dest => dest.Id, opts => opts.Ignore());
}

2) MapFrom()

MapFrom() can be used when you need to tell Automapper where to get the value for a property. Maybe, the names or the types are different; you can use MapFrom() in the following way:

public void BuildPublicMap(IMapperConfigurationExpression config)
{
    config.CreateMap<domainObject, dto>()
        .ForMember(dest => dest.propertyName, m => m.MapFrom(src => src.sourceProperty));
}

Or, if you need to set a value, like a date, the following example can be used:

public void BuildPublicMap(IMapperConfigurationExpression config)
{
    config.CreateMap<dto, domainObject>()
        .ForMember(dest => dest.CreatedDate, m => m.MapFrom(src => DateTime.Now));
}

3) ConstructUsing()

When your mapping is more difficult and you need to create custom code to handle it, you can use ConstructUsing(). There are many different reasons that you would need to use this like mapping properties from two objects into a single object. Here is an example:

public void BuildPublicMap(IMapperConfigurationExpression config)
{
    config.CreateMap<domainObject, dto>()
        .ConstructUsing(ConstructMapping);
}

private dto ConstructMapping(domainObject source)
{
    var dto = new dto();

    //custom code to map properties goes here
    return dto;
}

Automapper is a great tool that can be used when mapping objects. By using the three methods discussed above, you should be able to configure a map for almost any mapping you need without much headache.

If you this blog helped you or you would like to know more, please contact us with your questions or comments. Here at Sparkhound, our developers follow these and many other great coding practices, and we would love to have a conversation with you today about making your business the best it can be through leadership and technology.

Information and material in our blog posts are provided "as is" with no warranties either expressed or implied. Each post is an individual expression of our Sparkies. Should you identify any such content that is harmful, malicious, sensitive or unnecessary, please contact marketing@sparkhound.com.

Meet Sparkhound

Review our capabilities and services, meet the leadership team, see our valued partnerships, and read about the hardware we've earned.

Engage with us

Get in touch with any of our offices, or check out our open career positions and consider joining Sparkhound's dynamic team.