Используйте AutoMapper с пользовательским преобразованием для определенного свойства

Уважаемое интернет-сообщество.

Мне нужно отобразить элементы от одного объекта к другому. Классы идентичны (одно и то же имя класса, одинаковые свойства), поэтому я решил, что вместо этого мы должны попробовать AutoMapper. Кажется, это работает довольно хорошо, но я столкнулся с проблемой: один класс имеет object Свойство type, которое используется как своего рода контейнер подстановочного знака.

public class MyPet
{
    public int Id { get; set; }
    public object Pet{ get; set; }
}

public class Cat
{

}

public class Dog
{

}

Я изначально полагал, что AutoMapper сможет распознать тип экземпляра и выполнить соответствующее отображение в соответствии с инструкциями:

Mapper.CreateMap<LocalService.MyPet, ExternalService.MyPet>();
Mapper.CreateMap<LocalService.Cat, ExternalService.Cat>();
Mapper.CreateMap<LocalService.Dog, ExternalService.Dog>();


var dtoWithCat0 = new LocalService.MyPet()
{
    Id = 1,
    Item = new LocalService.Cat()
};

var dtoWithDog0 = new LocalService.MyPet()
{
    Id = 2,
    Item = new LocalService.Dog()
};

var dtoWithCat1 = Mapper.Map<ExternalService.MyPet>(dtoWithCat0);

var dtoWithDog1 = Mapper.Map<ExternalService.MyPet>(dtoWithDog0);

Console.WriteLine("{0}: {1} - {2}", dtoWithCat1.GetType().FullName, dtoWithCat1.Id, dtoWithCat1.Item.GetType().FullName);

Console.WriteLine("{0}: {1} - {2}", dtoWithCat1.GetType().FullName, dtoWithDog1.Id, dtoWithDog1.Item.GetType().FullName);

Тем не менее, это вывод:

ExternalService.MyPet: 1 - LocalService.Cat
ExternalService.MyPet: 2 - LocalService.Dog

Как видите, AutoMapper с удовольствием скопирует ссылку на объект свойства Item вместо создания нового экземпляра ExternalService.

Я ищу способ поручить AutoMapper разрешить Item свойство, основанное на пользовательской функции, что-то вроде этого:

object ConvertPet(object source)
{
    if (source is LocalService.Cat) return Mapper.Map<ExternalService.Cat>(source as LocalService.Cat);
    if (source is LocalService.Dog) return Mapper.Map<ExternalService.Dog>(source as LocalService.Dog);
}

Любые советы будут оценены!

-S

PS. Я заметил, что существует ConvertUsing метод. К сожалению, это, кажется, заменяет "автоматическую" часть AutoMapper настраиваемым явным отображением, которое должно реализовывать сопоставление всех свойств в DTO. Я хотел бы быть ленивым и иметь AutoMapper сделать исключение только для этого единственного свойства...

1 ответ

Решение

Может быть MapFrom поможет вам

Например

 Mapper.CreateMap<LocalService.MyPet, ExternalService.MyPet>()
            .ForMember(dest => dest.MyPet,
                        opt => opt.MapFrom(
                        src => ConvertPet(src.MyPet)));
Другие вопросы по тегам