2016-05-26 3 views
3

Только за вчера я отправил это:Automapper - Наследование картографа не работает с Конструкцией

Automapper - Inheritance mapper not working with type converter

Теперь я пытаюсь делать то, что @ сказал отмычка-Богард в своем ответе, но, к сожалению, до сих пор не имели успеха. Базовые элементы не отображаются.

Джимми сказал:

Однако, вы можете использовать ConstructUsing пристроить исходный объект назначения. Или пользовательский AfterMap, который также унаследован. Просто не конвертируется.

Вот мой новый код.

/* BaseClassConstructor.cs */ 
public class BaseClassConstructor { 
    public static BaseClass Construct(ResolutionContext context) { 
     if (context == null || context.IsSourceValueNull) 
      return null; 

     var src = (SourceClass)context.SourceValue; 

     return new BaseClass() { 
      CommonAttr = src.SourceAttr 
     }; 
    } 
} 

/* AutoMapperConfig.cs */ 
public static class AutoMapperConfig { 

    public static void RegisterMappings() { 
     AutoMapper.Mapper.Initialize(config => { 
     config 
      .CreateMap<SourceClass, BaseClass>() 
      .Include<SourceClass, DerivedClass1>() 
      .Include<SourceClass, DerivedClass2>() 
      .ConstructUsing(s => BaseClassConstructor.Construct(s)); 

     config 
      .CreateMap<SourceClass, DerivedClass1>() 
      .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
      .IncludeBase<SourceClass, BaseClass>(); 
     }); 
    } 
} 

Я что-то пропустил? Я использую ConstructUsing правильный путь?

Любая помощь будет оценена по достоинству.

+0

Чего вы хотите достичь? Создание Mapper.Map (источник) работает? – Evk

+0

Да! @Evk. При корректном отображении всех базовых атрибутов. – arosgab

+0

И вам нужно использовать конвертер типов? Потому что в вашем примере вам это действительно не нужно. – Evk

ответ

2

, как вы делаете это сейчас он не будет работать, потому что в ConstructUsing вы создаете экземпляр BaseClass, в то время, когда карта источника Derived1 класса - вам нужен экземпляр Derived1 класса, и BaseClass не может быть преобразован в том, что (опущенный). Однако вы можете сделать это следующим образом:

public class BaseClassConstructor { 
    public static T Construct<T>(ResolutionContext context) where T : BaseClass, new() { 
     if (context == null || context.IsSourceValueNull) 
      return null; 

     var src = (SourceClass) context.SourceValue; 

     return new T() { 
      CommonAttr = src.SourceAttr 
     }; 
    } 
} 

/* AutoMapperConfig.cs */ 
public static class AutoMapperConfig 
{ 

    public static void RegisterMappings() 
    { 
     AutoMapper.Mapper.Initialize(config => { 
      config 
       .CreateMap<SourceClass, BaseClass>(); 

      config 
       .CreateMap<SourceClass, DerivedClass1>() 
       .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
       .IncludeBase<SourceClass, BaseClass>() 
       .ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass1>(ctx)); 

      config 
       .CreateMap<SourceClass, DerivedClass2>() 
       .ForMember(dest => dest.Dummy, o => o.MapFrom(src => src.SourceAttr2)) 
       .IncludeBase<SourceClass, BaseClass>() 
       .ConstructUsing((s, ctx) => BaseClassConstructor.Construct<DerivedClass2>(ctx)); 
     }); 
    } 
} 

В принципе я изменил свой метод Construct, чтобы возвращать экземпляры производных классов тоже, а затем использовать ConstructUsing, но не на отображение базового класса, но на Derived классов отображений.

+0

Спасибо! Ты мне очень помог. Однако я не вижу необходимости в сопоставлениях наследования. Я просто удалил базовое сопоставление и оставил производные без вызова IncludeBase, и все прекрасно работает, потому что базовое отображение действительно происходит в производных сопоставлениях. – arosgab

+0

Да, я просто оставил это, если в реальной ситуации вы частично сопоставляете свойства базового класса с использованием ForMember и только картографируете сложные, используя Construct. В противном случае вам не нужно все это. – Evk

Смежные вопросы