使用 AutoMapper 进行集合的多态映射

2024-04-14

TL;DR:我在多态映射方面遇到了麻烦。我已经制作了一个 github 存储库,其中包含一个测试套件来说明我的问题。请在这里找到它:回购链接 https://github.com/780Farva/AutoMapperInquiry

我正在努力实现保存/加载功能。为了实现这一点,我需要确保我正在序列化的域模型以序列化友好的方式表示。为了实现这一目标,我创建了一组 DTO,其中包含进行有意义的保存或加载所需的最低限度的信息集。

对于域来说是这样的:

public interface IDomainType
{
  int Prop0 { get; set; }
}

public class DomainType1 : IDomainType
{
  public int Prop1 { get; set; }
  public int Prop0 { get; set; }
}

public class DomainType2 : IDomainType
{
  public int Prop2 { get; set; }
  public int Prop0 { get; set; }
}

public class DomainCollection
{
  public IEnumerable<IDomainType> Entries { get; set; }
}

...对于 DTO

public interface IDto
{
  int P0 { get; set; }
}

public class Dto1 : IDto
{
  public int P1 { get; set; }
  public int P0 { get; set; }
}

public class Dto2 : IDto
{
  public int P2 { get; set; }
  public int P0 { get; set; }
}

public class DtoCollection
{
  private readonly IList<IDto> entries = new List<IDto>();
  public IEnumerable<IDto> Entries => this.entries;
  public void Add(IDto entry) { this.entries.Add(entry); }
}

这个想法是 DomainCollection 代表应用程序的当前状态。目标是将 DomainCollection 映射到 DtoCollection 会生成一个 DtoCollection 实例,该实例在映射到域时包含 IDto 的适当实现。反之亦然。

这里的一个额外技巧是,不同的具体域类型来自不同的插件程序集,因此我需要找到一种优雅的方法来让 AutoMapper(或类似的,如果您知道更好的映射框架)为我完成繁重的工作。

使用 Structuremap,我已经能够从插件中找到并加载所有配置文件,并使用它们配置应用程序 IMapper。

我尝试过创建这样的配置文件......

public class CollectionMappingProfile : Profile
{
  public CollectionMappingProfile()
  {
    this.CreateMap<IDomainType, IDto>().ForMember(m => m.P0, a => a.MapFrom(x => x.Prop0)).ReverseMap();

    this.CreateMap<DtoCollection, DomainCollection>().
       ForMember(fc => fc.Entries, opt => opt.Ignore()).
       AfterMap((tc, fc, ctx) => fc.Entries = tc.Entries.Select(e => ctx.Mapper.Map<IDomainType>(e)).ToArray());

    this.CreateMap<DomainCollection, DtoCollection>().
       AfterMap((fc, tc, ctx) =>
                {
                  foreach (var t in fc.Entries.Select(e => ctx.Mapper.Map<IDto>(e))) tc.Add(t);
                });
}

public class DomainProfile1 : Profile
{
  public DomainProfile1()
  {
    this.CreateMap<DomainType1, Dto1>().ForMember(m => m.P1, a => a.MapFrom(x => x.Prop1))
      .IncludeBase<IDomainType, IDto>().ReverseMap();
  }
}

public class DomainProfile2 : Profile
{
  public DomainProfile2()
  {
    this.CreateMap<DomainType2, IDto>().ConstructUsing(f => new Dto2()).As<Dto2>();

    this.CreateMap<DomainType2, Dto2>().ForMember(m => m.P2, a => a.MapFrom(x => x.Prop2))
      .IncludeBase<IDomainType, IDto>().ReverseMap();
  }
}

然后,我编写了一个测试套件,以确保在将此功能与应用程序集成时映射将按预期运行。我发现每当 DTO 映射到域(例如 Load)时,AutoMapper 都会创建 IDomainType 的代理,而不是将它们解析到域。

我怀疑问题出在我的地图配置文件上,但我已经没有人才了。预先感谢您的意见。

这是 github 存储库的另一个链接 https://github.com/780Farva/AutoMapperInquiry


我自己在研究多态映射问题时偶然发现了这个问题。答案很好,但如果您想从基本映射角度处理它并且有许多派生类,那么这只是另一种选择,您可以尝试以下操作:

CreateMap<VehicleEntity, VehicleDto>()
    .IncludeAllDerived();

CreateMap<CarEntity, CarDto>();
CreateMap<TrainEntity, TrainDto>();
CreateMap<BusEntity, BusDto>();

See the 自动映射器文档 http://docs.automapper.org/en/stable/Mapping-inheritance.html了解更多信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 AutoMapper 进行集合的多态映射 的相关文章

随机推荐

  • 选择给定点集中最远点的子集

    想象一下 你有一个 3 维 n 个点的集合 S 任意两点之间的距离是简单的欧几里得距离 您想要从该集合中选择 k 个点的子集 Q 以使它们彼此相距最远 换句话说 不存在 k 个点的其他子集 Q 使得 Q 中所有成对距离的最小值小于 Q 中的
  • 如何自动更新最大值?

    在串行代码中 更新最大值可以简单地通过以下方式完成 template
  • Winforms:SuspendLayout/ResumeLayout 还不够?

    我有一个包含一些 自定义控件 的库 本质上 我们有自己的按钮 圆角面板和一些带有一些自定义油漆的分组框 尽管 OnPaint 方法中存在 数学 但控件还是相当标准的 大多数时候 我们所做的只是绘制圆角并向背景添加渐变 我们使用 GDI 来实
  • ADO.NET 实体框架中的乐观并发

    I found MSDN 文章 http msdn microsoft com en us library bb738618 v vs 90 aspx描述了 EF 在保存更改时如何处理并发 默认情况下 对象服务保存对象 对数据库的更改没有
  • 查找 javascript 数组中的空索引列表

    Javascript 有没有办法找到数组为空或不包含 x 的索引 x x 会返回类似 1 2 4 5 6 我尝试过这样的事情 empty roster findIndex obj gt Object keys obj length 0 但是
  • 如何在 _layout.cshtml 中使用 data-ng-view

    我正在尝试使用 Angular 创建 MVC 应用程序 我的应用程序有通用的页眉和页脚 所以我将其添加到 layout cshtml中 应用程序中有一些静态页面 因此我想使用 Angular 路由来加载它 这是我的 layout cshtm
  • JQuery UI Datepicker:如何添加下一年/上一年按钮

    我使用通过下拉菜单选择年份的功能 我用它来设置至少 18 岁的人的生日 到目前为止 它运行得很好 我已经使用这些参数进行了设置 datepicker datepicker changeMonth true changeYear true d
  • git diff HEAD 与 git diff --staged 之间有什么区别?

    有什么区别git diff HEAD and git diff staged 我尝试了两者 但都给出了相同的输出 假设这个输出为git status git status On branch master Changes to be com
  • 如何在android中使用xml布局进行绘制

    我正在尝试完成开发人员页面上给出的 android 示例 它提供了两种在画布上绘图的方法 第一种方法是使用名为 CustomDrawableView 的类 如下所示 public class CustomDrawableView exten
  • 如何清除 WPF Frame 控件托管的整个导航历史记录

    在 WPF 应用程序中 Frame 控件用于托管 导航页面 我想清除导航历史记录 有 NavigationService RemoveBackEntry 方法可用于清除历史记录的向后部分 但是前向导航历史又如何呢 这部分怎么清除呢 最佳实践
  • Android WebView 显示纯文本而不是 html

    首先 我想说这只是 Android 2 及更早版本上的问题 4 似乎不受影响 我没有测试 3 我有一个WebView从字符串加载 html HTML 看起来像这样 h1 Hello World h1 您可以看到 css 文件如下所示 bod
  • H2DB WITH 子句

    我正在使用以下 sql 为方法编写单元测试 WITH temptab i id i name i effective i expires i lefttag i righttag hier id hier dim id parent ite
  • iPad 弹出文本字段 - resignFirstResponder 不会关闭键盘

    我有两个文本字段电子邮件和密码 当字段显示在常规视图上时 以下代码工作正常 但当它们显示在弹出窗口上时 resignFirstResponder 不起作用 becomeFirstResponder 起作用 为这两个字段调用了 textFie
  • 将 C dll 代码编组为 C#

    我在 dll 中有以下 C 代码签名 extern declspec dllexport unsigned char funct name int w int h char enc int len unsigned char text in
  • 当使用 apply() 和 call() 方法很容易继承时,为什么人们在 JavaScript 中使用原型?

    形状由矩形继承 这种继承可以通过多种方法来完成 这里我使用了apply 和call 当子类的draw方法被调用时 从该方法中再次调用基类的draw方法 我通过两种方式完成了这件事 一种是制作基类的原型绘制方法 另一种是使用 apply 和
  • Google 应用引擎 - 如何禁用缓存

    所以一些背景 我有一个在谷歌应用程序引擎上运行的nodeJS api 默认情况下 应用程序引擎会将我的所有获取请求缓存 10 分钟 我将 cloudflare 用于我的 API 因为这允许我在需要时从缓存中删除特定项目 您可以想象这会引起一
  • Swift iOS - 标签集合视图

    我正在编写我的第一个 iOS 应用程序 我只想回答最知名的解决方案是什么 这是简单的标签收集 我已经在互联网上查看过 但一无所获 我认为最好的方法可能是制作我自己的按钮结构 这是我想要实现的目标 有时你需要自己做 import UIKit
  • 在 Visual Studio Code 中自动导入以进行 React-Native 开发 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有扩展名吗VS Code这使得自动导入 for 反应本机组件 例如 当我打字时
  • 异步映射中的同步部分

    我有一个大的 IO 函数 它将持续从文件夹加载数据 对数据执行纯计算 然后写回 我正在多个文件夹上并行运行此函数 mapConcurrently iofun folderList from http hackage haskell org
  • 使用 AutoMapper 进行集合的多态映射

    TL DR 我在多态映射方面遇到了麻烦 我已经制作了一个 github 存储库 其中包含一个测试套件来说明我的问题 请在这里找到它 回购链接 https github com 780Farva AutoMapperInquiry 我正在努力