c# - 一种类型到另一种类型的映射列表

标签 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>();

最佳答案

这里 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,在这种情况下它无法猜测。

关于c# - 一种类型到另一种类型的映射列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2324429/

相关文章:

c# - 如何在 .Net Core Web API 项目中对使用 Mapper 的方法进行单元测试

C# Automapper -> 条件映射

c# - 如何使用 Automapper 映射父/子集合模型?

interface - 自动映射器 : Mapping to an Interface

c# - 法线贴图与动态贴图的区别 - automapper

c# - 如何使 WPF 窗口位于我的应用程序的所有其他窗口之上(不是系统范围的)?

c# - 如何在不使用等待的情况下在系统托盘中显示进度指示器几秒钟 [Windows Phone 8]

c# - 在空 IEnumerable<int> 上为 FirstOrDefault() 返回 null?

c# - 在 C# 中使用 GetType/instanceof 与替代方案

c# - Specflow - 对任何关键字使用相同的步骤定义