21

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?
Ian Vink
  • 66,960
  • 104
  • 341
  • 555

4 Answers4

23

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.

Community
  • 1
  • 1
Mightymuke
  • 5,094
  • 2
  • 31
  • 42
17

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>();
Bala
  • 512
  • 9
  • 16
Behnam Esmaili
  • 5,835
  • 6
  • 32
  • 63
2

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

Dmitry Efimenko
  • 10,973
  • 7
  • 62
  • 79
  • I don't think it gives a compilation error if I remember correctly... it gives a runtime error? No mapping for B,A found or something along those lines? – Alex Dec 17 '12 at 17:44
  • that's right... I remembered that it gives some kind of an error. – Dmitry Efimenko Dec 17 '12 at 18:14
1

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.

Alexz S.
  • 2,366
  • 4
  • 21
  • 34