2010-02-24 4 views
4

Pour mes objets, j'utilise Csla, qui possède une propriété BrokenRulesCollection. Je voudrais convertir cela à mon propre DTO qui a la propriété StatusMessages.Mappage d'un type à un autre

J'ai créé mon propre résolveur:

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

Et dans la cartographie, je le faire savoir qui résolveur à utiliser:

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

Cependant, lorsque je tente de faire la mise en correspondance:

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

je reçois l'erreur suivante:

La valeur fournie est de type Csla.Validation.BrokenRulesCollection mais attend Favs.DomainObjects.Members.MemberRegistration. Modifiez le type de source du résolveur de valeur ou redirigez la valeur source fournie au résolveur de valeur à l'aide de FromMember.

Des suggestions?

Edit:

En guise de suivi, je l'ai aussi essayé de créer un converti, mais toujours le même message:

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

et le configurer comme suit:

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

Après votre modification, avez-vous également supprimé la configuration "ResolveUsing" dans le mappage IMemberRegistration? –

Répondre

7

L'instance que AutoMapper passe en ResolveCore n'est pas le BrokenRulesCollection - AutoMapper ne sait pas quelle propriété du IMemberRegistration pour l'obtenir. Lorsque vous utilisez un résolveur personnalisé, il obtient une instance du même objet que vous essayez de mapper.

Il devrait fonctionner si vous réécrivez votre première classe comme ceci:

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

Remarque - Je suppose que le membre que vous souhaitez mapper sur IMemberRegistration est une propriété appelée BrokenRules. Changez ceci à tout ce qui s'applique.

Edit - vous pouvez aussi faire ce que le message suggère et utiliser FromMember:

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

Encore une fois, cela suppose la propriété est nommé BrokenRules. Vous devez le dire à AutoMapper, il ne peut pas deviner dans ce cas.

+0

Cela fonctionne très bien! Est-il possible de déclarer un résolveur ou un convertisseur entre les deux types de listes? Beaucoup de mes objets ont le BrokenRulesCollection et doivent convertir à StatusMessageList de mon DTO. Je voudrais éviter d'avoir un résolveur différent pour chaque paire. –

+0

@Andy: Mon deuxième exemple peut être utilisé avec votre résolveur d'origine qui ne dépend que de 'BrokenRulesCollection' (puisque vous indiquez à AutoMapper quelle propriété spécifique utiliser avec' FromMember'). Vous pouvez utiliser le même résolveur pour chaque objet composite, il vous suffit de vous assurer d'ajouter 'FromMember' à chaque mapping. – Aaronaught

Questions connexes