将一种类型的列表映射到另一种类型

时间:2010-02-24 07:55:23

标签: c# automapper

对于我的对象,我使用的是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>();

1 个答案:

答案 0 :(得分: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,在这种情况下无法猜测。