2010-02-24 141 views
4

对于我的对象,我使用Csla,它具有BrokenRulesCollection属性。我想将其转换为具有StatusMessages属性的我自己的DTO。将一种类型的映射列表映射到另一种

我创造了我自己的解析器:

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重定向提供给值解析器的源值。

有什么建议吗?

编辑:

作为后续行动,我也试图创建一个转换,但仍然得到了同样的信息:

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

继编辑之后,您是否还删除了IMemberRegistration映射中的“ResolveUsing”配置? – 2010-02-25 13:50:16

回答

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属性。将此更改为适用的内容。

编辑 - 你也可以做消息表明什么,使用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,需要转换为我的DTO的StatusMessageList。我想避免为每一对使用不同的解析器。 – 2010-02-25 07:26:03

+0

@Andy:我的第二个例子可以与你的原始解析器一起使用,它只依赖于'BrokenRulesCollection'(因为你告诉AutoMapper哪个特定的属性用于'FromMember')。您可以为每个复合对象使用相同的解析器,只需确保将'FromMember'添加到每个映射。 – Aaronaught 2010-02-25 14:28:01

相关问题