У меня возникли проблемы с внедрением преобразования Automapper в ситуации, когда источником является класс, который должен быть сопоставлен с одним из двух производных классов на основе значения источника.Карта для определенного производного типа на основе значения источника с помощью Automapper
Вот упрощение моих классов:
public class FooContainerDTO
{
public FooDTO Foo { get; set; }
}
public class FooDTO
{
public string Type { get; set; }
//some properties..
}
public class FooContainer
{
public FooBase Foo { get; set; }
}
public abastract class FooBase
{
//some properties..
}
public class FooDerived1 : FooBase
{
//some properties
}
public class FooDerived2 : FooBase
{
//some properties
}
Я использую нестатический Automapper поэтому я создаю MapperConfiguration из нескольких профилей при загрузке и впрыснуть экземпляр IMapper в мой DI-контейнер. Я хочу, чтобы Automapper отображал FooDTO в FooDerived1, когда его свойство типа «der1» и FooDerived2, когда оно «der2».
Я видел примеры на этот счет, используя статический API, что-то вроде этого:
Mapper.CreateMap<FooContainerDTO, FooContainer>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooDerived1>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooDerived2>();
//ForMember configurations etc.
Mapper.CreateMap<FooDTO, FooBase>()
.ConvertUsing(dto => dto.Type == "der1"
? (FooBase) Mapper.Map<FooDerived1>(dto)
: Mapper.Map<FooDerived2>(dto));
Это карта свойство Foo из FooContainer к правильному производного типа FooBase.
Но как я могу это сделать без статического API? Экземпляр IMapper еще не создан в момент настройки профиля. Есть ли способ использовать перегрузку ConvertUsing(), которая принимает Func < ResolutionContext, object>? Может ли контекст разрешения дать мне то, что в настоящее время используется IMapper? Я искал, но не могу найти ничего полезного.
Итак, как ни странно, я использовал для этого немного временного взлома. У меня есть собственный класс TypeConverter, который содержит 'IMapper _defaultEngine = MyGlobalConfig.Engine'. Затем я создаю две конфигурации: одну, использующую статический глобальный, и другую, которую я размещаю в своем собственном статическом местоположении и использую в качестве «резервной» для более простых сопоставлений. –
Это, вероятно, работает, но «взломать» - это правильное имя :) Я немного взломал себя, чтобы заставить его работать; вместо того, чтобы вставлять сам IMapper в DI, я добавляю экземпляр MapperContainer, который имеет свойство удерживать фактический экземпляр IMapper. Затем я могу ввести MapperContainer в свой профиль и настроить ConvertUsing-lambdas для доступа к свойству mapper, даже если он будет NULL до тех пор, пока bootstrapper не установит экземпляр IMapper. –
На самом деле, снова глядя на вашу проблему, почему вы не можете просто создать TypeConverter и использовать 'ResolutionContext.Engine.Map' внутри' Convert'? –