2010-02-24 2 views
4

Для моих объектов я использую Csla, у которого есть свойство BrokenRulesCollection. Я хотел бы преобразовать это в свой собственный DTO, у которого есть свойство StatusMessages.Сопоставление списка одного типа, другому

Я создал свой собственный распознаватель:

public class BrokenRulesCollectionResolver : ValueResolver<Csla.Validation.BrokenRulesCollection, StatusMessageList> 
{ 
    protected override StatusMessageList ResolveCore(Csla.Validation.BrokenRulesCollection source) 
    { 
     var messageList = new StatusMessageList(); 
     messageList.ReadBrokenRules(source); 
     return messageList; 
    } 
} 

И в отображении, я позволяю это знать, какое решающее использовать:

 Mapper.CreateMap<DomainObjects.Members.IMemberRegistration, DTO.Members.MemberRegistrationForm>() 
      .ForMember(src => src.StatusMessages, opt => opt.ResolveUsing <BrokenRulesCollectionResolver>()); 

Однако, когда я пытаюсь сделать отображение:

 return Mapper.Map<DomainObjects.Members.IMemberRegistration, DTO.Members.MemberRegistrationForm>(memberRegistration); 

Я получаю следующее сообщение об ошибке:

Приведенное значение имеет тип Csla.Validation.BrokenRulesCollection, но ожидается Favs.DomainObjects.Members.MemberRegistration. Измените тип источника распознавателя значения или перенаправьте исходное значение, заданное в преобразователь значения, используя функцию FromMember.

Любые предложения?

Edit:

В продолжение, я также пытался создать новообращенный, но все еще получаю такое же сообщение:

public class BrokenRulesCollectionConverter : ITypeConverter<Csla.Validation.BrokenRulesCollection, StatusMessageList> 
{ 
    public StatusMessageList Convert(ResolutionContext context) 
    { 
     var test = new StatusMessageList(); 
     test.ReadBrokenRules((Csla.Validation.BrokenRulesCollection)context.SourceValue); 
     return test; 
    } 
} 

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

 Mapper.CreateMap<Csla.Validation.BrokenRulesCollection, StatusMessageList>() 
      .ConvertUsing<BrokenRulesCollectionConverter>(); 
+0

После вашего редактирования вы также удалили конфигурацию «ResolveUsing» в картографии IMemberRegistration? –

ответ

7

Экземпляр, который AutoMapper передает в ResolveCore, здесь не BrokenRulesCollection - AutoMapper не знает какое свойство IMemberRegistration, чтобы получить это. Когда вы используете пользовательский преобразователь, он получает экземпляр того же объекта, который вы пытаетесь сопоставить.

Он должен работать, если вы переписать свой первый класс, как так:

public class BrokenRulesCollectionResolver : 
    ValueResolver<DomainObjects.Members.IMemberRegistration, StatusMessageList> 
{ 
    protected override StatusMessageList ResolveCore(
     DomainObjects.Members.IMemberRegistration source) 
    { 
     var messageList = new StatusMessageList(); 
     messageList.ReadBrokenRules(source.BrokenRules); 
     return messageList; 
    } 
} 

Примечание - Я предполагаю, что член вы хотите отобразить на IMemberRegistration это свойство называется BrokenRules. Измените это применительно.

Edit - вы можете делать то, что предлагает сообщение и использовать FromMember:

Mapper.CreateMap<DomainObjects.Members.IMemberRegistration, 
    DTO.Members.MemberRegistrationForm>() 
     .ForMember(src => src.StatusMessages, 
      opt => opt 
       .ResolveUsing<BrokenRulesCollectionResolver>() 
       .FromMember(r => r.BrokenRules)); 

Опять же, это предполагает, что свойство с именем BrokenRules. Вы должны сказать AutoMapper, в этом случае он не может догадаться.

+0

Это отлично работает! Можно ли объявить Resolver или Converter между двумя типами списков? Многим моим объектам принадлежит BrokenRulesCollection и нужно преобразовать его в свой статус StatusMessageList. Я бы хотел, чтобы у каждой пары не было другого Resolver. –

+0

@ Andy: Мой второй пример можно использовать с вашим исходным резольвером, который зависит только от 'BrokenRulesCollection' (поскольку вы указываете AutoMapper, какое конкретное свойство использовать с' FromMember'). Вы можете использовать один и тот же резольвер для каждого составного объекта, вам просто нужно добавить «FromMember» к каждому сопоставлению. – Aaronaught

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