Why is a custom resolver needed here (AutoMapper)?

513 views Asked by At

Given the following entity model:

public class Location
{
    public int Id { get; set; }
    public Coordinates Center { get; set; }
}
public class Coordinates
{
    public double? Latitude { get; set; }
    public double? Longitude { get; set; }
}

... and the following view model:

public class LocationModel
{
    public int Id { get; set; }
    public double? CenterLatitude { get; set; }
    public double? CenterLongitude { get; set; }
}

The LocationModel properties are named such that mapping from the entity to the model does not require a custom resolver.

However when mapping from a model to an entity, the following custom resolver is needed:

CreateMap<LocationModel, Location>()
    .ForMember(target => target.Center, opt => opt
        .ResolveUsing(source => new Coordinates 
            { 
                Latitude = source.CenterLatitude, 
                Longitude = source.CenterLongitude 
            }))

Why is this? Is there a simpler way to make AutoMapper to construct a new Coordinates value object based on the naming conventions in the viewmodel?

Update

To answer the first comment, there is nothing special about the entity to viewmodel mapping:

CreateMap<Location, LocationModel>();
1

There are 1 answers

3
devuxer On BEST ANSWER

Edit

Please see comment thread below. This answer is actually for the opposite mapping.


You're doing something else wrong. You are following the convention correctly, so the mapping should work without any need for a resolver.

I just tried this test, and it passed:

public class Location
{
    public int Id { get; set; }
    public Coordinates Center { get; set; }
}

public class Coordinates
{
    public double? Latitude { get; set; }
    public double? Longitude { get; set; }
}

public class LocationModel
{
    public int Id { get; set; }
    public double? CenterLatitude { get; set; }
    public double? CenterLongitude { get; set; }
}

[Test]
public void LocationMapsToLocationModel()
{
    Mapper.CreateMap<Location, LocationModel>();

    var location = new Location
    {
        Id = 1,
        Center = new Coordinates { Latitude = 1.11, Longitude = 2.22 }
    };

    var locationModel = Mapper.Map<LocationModel>(location);

    Assert.AreEqual(2.22, locationModel.CenterLongitude);
}