Using Automapper I create a simple map:
Mapper.CreateMap<MyCustomerDTO, YourCustomerDTO>()
I often need to go the other way too. Do I need to also create the mapping the other way, or will Automapper infer it based on the above mapping?
Mapper.CreateMap<YourCustomerDTO, MyCustomerDTO>() //Needed?
No. you must create two way mapping. A good helper method for two way mapping could be :
protected virtual void ViceVersa<T1, T2>()
{
Mapper.CreateMap<T1, T2>();
Mapper.CreateMap<T2, T1>();
}
then use it like this :
ViceVersa<T1, T2>();
This is a duplicate to Do i need to create automapper createmap both ways?
Note the answer regarding .ReverseMap()
here.
Note that .ReverseMap()
is for basic mapping. If you need to use options (such as specific ForMember
mappings), you will need to create a custom reverse map.
you need to create second mapping as well. A simple test trying to run your app without second mapping will give you a runtime error
I've come across the same issue when working with AutoMapper, and @Behnam-Esmaili is a good answer but it could be improved.
You could implement a extension method for IMapperConfigurationExpression
which would do this two way mapping and also expecting two optional parameter (Action<IMappingExpression<T, Y>>
) which would be used when trying to configure the Mappings for both types.
public static class ModelMapper
{
private static readonly IMapper _mapper;
static ModelMapper()
{
var mapperConfiguration = new MapperConfiguration(config =>
{
config.CreateTwoWayMap<CustomerViewModel, Customer>(
secondExpression: (exp) => exp.ForMember((source) => source.CustomerEmail, opt => opt.MapFrom(src => src.Email)));
});
_mapper = mapperConfiguration.CreateMapper();
}
public static void CreateTwoWayMap<T, Y>(this IMapperConfigurationExpression config,
Action<IMappingExpression<T, Y>> firstExpression = null,
Action<IMappingExpression<Y, T>> secondExpression = null)
{
var mapT = config.CreateMap<T, Y>();
var mapY = config.CreateMap<Y, T>();
firstExpression?.Invoke(mapT);
secondExpression?.Invoke(mapY);
}
public static T Map<T>(object model)
{
return _mapper.Map<T>(model);
}
}
The implementation above is a one way of achieving it, however it can be design differently.