AutoMapper: отображает ли карта <A, B> <B, A>?

Использование Automapper Я создаю простую карту:

Mapper.CreateMap<MyCustomerDTO, YourCustomerDTO>()

Мне часто нужно идти другим путем. Нужно ли мне также создавать сопоставление другим способом, или Automapper вывести его на основе приведенного выше отображения?

Mapper.CreateMap<YourCustomerDTO, MyCustomerDTO>()   //Needed?

Ответ 1

Нет. вы должны создать двухстороннее сопоставление. Хорошим вспомогательным методом для двухстороннего отображения может быть:

 protected virtual void ViceVersa<T1, T2>()
        {
            Mapper.CreateMap<T1, T2>();
            Mapper.CreateMap<T2, T1>();
        }

то используйте его следующим образом:

ViceVersa<T1, T2>();

Ответ 2

Это дубликат для Нужно ли создавать файл Sitemap automapper в обоих направлениях?

Обратите внимание на ответ .ReverseMap() здесь.

Обратите внимание, что .ReverseMap() - для базового сопоставления. Если вам нужно использовать параметры (например, конкретные сопоставления ForMember), вам необходимо создать пользовательскую обратную карту.

Ответ 3

вам нужно также создать второе сопоставление. Простой тест, пытающийся запустить ваше приложение без второго сопоставления, даст вам ошибку времени выполнения

Ответ 4

Я столкнулся с той же проблемой при работе с AutoMapper, а @Behnam-Esmaili - хороший ответ, но он может быть улучшен.

Вы можете реализовать метод расширения для IMapperConfigurationExpression, который бы сделал это двухстороннее сопоставление, а также ожидал два необязательных параметра (Action<IMappingExpression<T, Y>>), которые будут использоваться при попытке настроить сопоставления для обоих типов.

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);
    }
}

Реализация выше - это один из способов ее достижения, однако он может быть выполнен по-разному.