可能是.NET领域性能最好的对象映射框架——Mapster

我之前文章提到过 MediatR 的作者 Jimmy Bogard,他也是大名鼎鼎的对象映射框架 AutoMapper 的作者。AutoMapper 的功能强大,在 .NET 领域的开发者中有非常高的知名度和使用率。而今天老衣要提的是另外一款高性能对象映射框架:Mapster——它轻巧便捷,功能也非常强大,关键是性能很高——有可能是.NET领域性能最好的。

我们先来看看性能

与 AutoMapper 相比,Mapster 在速度和内存占用方面表现更加优秀 ,下面是官方给出的稍早版本 6.0 的性能对比表:

MethodMeanStdDevErrorGen 0Gen 1Gen 2Allocated
'Mapster 6.0.0'108.59 ms1.198 ms1.811 ms31000.0000--124.36 MB
'Mapster 6.0.0 (Roslyn)'38.45 ms0.494 ms0.830 ms31142.8571--124.36 MB
'Mapster 6.0.0 (FEC)'37.03 ms0.281 ms0.472 ms29642.8571--118.26 MB
'Mapster 6.0.0 (Codegen)'34.16 ms0.209 ms0.316 ms31133.3333--124.36 MB
'ExpressMapper 1.9.1'205.78 ms5.357 ms8.098 ms59000.0000--236.51 MB
'AutoMapper 10.0.0'420.97 ms23.266 ms35.174 ms87000.0000--350.95 MB

从表中我们可以看出,即使在不使用高性能组件的情况下它的性能都可以获得4倍于AutoMapper,却只需要1/3左右的内存占用,而在使用Roslyn CompilerFEC (FastExpressionCompiler)Code generation等组件后可以再进一步提升2-3倍的性能。Code generation 方式几乎就是这个事儿极限了。你还有更快的手段吗?

在实际项目中的基本使用

首先从 Nuget 中引用最新版本的 Mapster 包:

dotnet add package Mapster

对象映射最多的场景就是两个实体定义的属性名是重叠对应的,那么此时的基本用法就非常简单:

var destObject = sourceObject.Adapt<Destination>();

「注意」我说的是实体定义,没有只限制类定义。Class、Record(有点小限制注意查阅官方文档)、Interface 等各种形式都可以哦,这是我非常喜欢的。当然了你的源是IQueryable的也可以!

不是类也不是接口,只是基本的简单类型是否可以呢?也可以!

var s = 123.Adapt<string>(); // 等同于: 123.ToString();

列表、数组、集合、包括各种接口的字典之间的映射,也可以: IList<T>, ICollection<T>, IEnumerable<T>, ISet<T>, IDictionary<TKey, TValue> 等等都可以!

只要C#支持类型转换的类型,那么在 Mapster 中也同样支持转换,而且像枚举与字符串之间的转换,.NET 自带的方式性能稍慢,Mapster也针对性的做了优化,所以你实际生产中绝大部分就是类似上面这么一行代码就行了,够简单便捷吧 :D

在某些情况下,需要依赖注入,Mapster 提供了 IMapperMapper 来满足这个需求:

var result = mapper.Map<TDestination>(source);

映射配置

现实项目中难免会有一些自定义映射的需求,Mapster提供了很强大的映射配置机制,可以通过映射配置解决你各种灵活需求。

我们可以使用 TypeAdapterConfig<TSource, TDestination>.NewConfig()TypeAdapterConfig<TSource, TDestination>.ForType() 配置类型映射;

「注意」当调用 NewConfig 方法时,将会覆盖已存在的类型映射配置。

TypeAdapterConfig<TSource, TDestination>.NewConfig().Ignore(dest => dest.Age).Map(dest => dest.FullName,src => string.Format("{0} {1}", src.FirstName, src.LastName));

当然了你想让自己配置全局有效,可以通过对 TypeAdapterConfig.GlobalSettings 进行设置处理。

你有一些场景需要有条件规则?没问题,可以通过When方法来实现:

TypeAdapterConfig.GlobalSettings.When((srcType, destType, mapType) => srcType == destType).Ignore("Id");

上面这个配置的意思是,应用全局范围当任何一个映射的源类型和目标类型相同时,不映射 Id 属性。

新版本中对接口只读属性映射的增强

最近刚刚发布对 Mapster 7.3.0 带来了一些新的增强:

  • Switch expression by @SergerGood in #334

  • Upgrade packages by @SergerGood in #333

  • Include .NET 6.0 as Target Framework for Mapster.Tool by @kaizen365 in #390

  • Updated Sample Code in Readme by @CoSJay in #379

  • Simplify packaging and publishing NuGet packages, remove old framework monikers and upgrade to C# 10.0 by @andrerav in #405

  • Add ability to compile all mappings and then throw AggregateException by @MisterOzzy in #363

  • Init read-only properties when mapping with a non-readonly interface fixes #374 by @andrei-traktatovich in #375

其中最后一下对接口的只读属性映射增强,是我非常喜欢的,解决了在实际项目中的设计需求,省了不少事儿。

public interface ITarget
{int GetOnlyProperty {get;}int NormalProperty {get;set;}
}
public interface ITargetWithGetSetProperties
{int GetOnlyProperty {get;}int NormalProperty {get;set;}
}

上面这个代码中场景中,如果ITarget类型的对象的属性 GetOnlyProperty 带有一个非 0 值,并想 Map 为 ITargetWithGetSetProperties 类型的对象时,老版本会在映射后目标对象的GetOnlyProperty保留int类型的默认值0,没做任何映射,新版本中解决了这个问题!

你可能会问“为什么会有这个需求?”,嗯,一个原因是因为接口可以多继承,而类只能单一继承,你品品,细品…… :D

其他

微信公众号文章不适合详细展开讨论和分享,本文主要是抛砖引玉。想详细了解这个框架的可以到官方代码库中去看一下 https://github.com/MapsterMapper/Mapster ,如果说英文阅读有点困难,可以到 https://github.com/rivenfx/Mapster-docs 看热心网友做到中文翻译版。

00a8f65e79e42ddec154cad3af6dc701.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/290868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Avalonia跨平台入门第一篇

作为一枚屌丝程序员来说最大的爱好就是撸代码,有时候根本停不下来(沉迷工作,无法自拔);因为一直都是WPF开发,后面也摸索了一下Xamarin的东西;这不又看到其他人又在搞什么跨平台;我也是手也很痒痒;就像刚开始摸索Xamarin一样,想又不知如何下手;这不再次迈出了第一步去摸索Avalon…

三角形带优化库nvtrisrip的使用

nvtrisrip是NVIDIA提供的一个开源优化库&#xff0c;这个库可以将三角形顶点索引数组转换为三角形带索引数组。可以极大的提高渲染速度。NVIDIA这个库的官方地址是&#xff1a;http://www.nvidia.com/object/nvtristrip_library.html不过这里代码不全也不够新&#xff0c;推荐从…

angular-ui-tab-scroll

2019独角兽企业重金招聘Python工程师标准>>> A scrollable tab plugin intended for scrolling UI Bootstrap tabset. 功能介绍&#xff1a;http://npm.taobao.org/package/angular-ui-tab-scroll 下载地址&#xff1a;https://github.com/VersifitTechnologies/ang…

为什么?

为什么80%的码农都做不了架构师&#xff1f;>>> 为什么总有那么多的难以忘怀&#xff1f;或许这是前世我们欠下的债吧为什么总觉得别人家的好&#xff1f;却忽视了身边最真实的温暖为什么总是固执的坚持着虚幻的前景&#xff1f;因为就算再小的梦想也有实现的权利为…

抽象类和接口类的区别

2019独角兽企业重金招聘Python工程师标准>>> 一、 抽象类abstract class 1 &#xff0e;抽象类是指在 class 前加了 abstract 关键字且存在抽象方法&#xff08;在类方法 function 关键字前加了 abstract 关键字&#xff09;的类。 2 &#xff0e;抽象类不能被直接实…

浅谈C#字符串构建利器StringBuilder

前言在日常的开发中StringBuilder大家肯定都有用过&#xff0c;甚至用的很多。毕竟大家都知道一个不成文的规范&#xff0c;当需要高频的大量的构建字符串的时候StringBuilder的性能是要高于直接对字符串进行拼接的&#xff0c;因为直接使用或都会产生一个新的String实例&#…

linux之如何在任意目录执行我常用的脚本文件

1、问题 比如我们在ubuntu上开发Android的时候&#xff0c;经常会用到jadx、 pidcat.py ,但是我们希望在任何目录都能执行这些命令&#xff0c; 如果不知道pidcat.py是什么东西的&#xff0c;可以先百度 2、解决方式 1)如果是一个脚本文件&#xff0c;比如pidcat.py这个脚本&…

RTMPdump(libRTMP) 源代码分析 10: 处理各种消息(Message)

2019独角兽企业重金招聘Python工程师标准>>> 注&#xff1a;此前写了一些列的分析RTMPdump&#xff08;libRTMP&#xff09;源代码的文章&#xff0c;在此列一个列表&#xff1a;RTMPdump 源代码分析 1&#xff1a; main()函数RTMPDump&#xff08;libRTMP&#xff…

Dapr 助力应用架构的可持续性

在文章亚马逊可持续软件工程实践[1] 有这么一段我们为什么要关注“可持续发展”&#xff1a;联合国于 2015 年制定了一个全球框架《巴黎协定》[2]&#xff0c;随后各缔约国纷纷制定了“碳中和”路径和目标&#xff0c;对地球环境的健康发展做出承诺。今年两会&#xff0c;中国也…

计算机无法创建新文件夹,无法创建文件,教您无法新建文件夹怎么办

在使用电脑的过程中&#xff0c;都遇到过电脑出现各种故障的情况&#xff0c;让不少的用户感到懊恼的时刻时有发生&#xff0c;造成非常大的不便&#xff0c;该怎么解决这个烦恼呢&#xff1f;下面&#xff0c;小编给大家分享无法新建文件夹的解决经验。相信在使用电脑是一定会…

我的技术回顾那些与ABP框架有关的故事-2018年

我的技术回顾那些与ABP框架有关的故事-2018年今天准备想写18年的&#xff0c;但是发现我从19年开始就在逐渐淡出社区&#xff0c;因为生活、工作的缘故吧。所以也没什么特别罗列的&#xff0c;就合并下吧。时间真的是可以磨平太多东西了&#xff0c;如果我不去整理资料的话&…

wpa_supplicant 无线网络配置

为什么80%的码农都做不了架构师&#xff1f;>>> 安装wpa_supplicant后&#xff0c;修改服务&#xff0c;编辑 /usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service 将下面的 [D-BUS Service] Namefi.epitest.hostap.WPASupplicant Exec/s…

Avalonia跨平台入门第六篇之Grid动态分割

前面玩耍了ListBox多选,今天在他的基础上对Grid进行动态分割;这个效果其实在Xamarin中已经实现过了;其实都没太大区别;直接看效果吧:在ListBox中选择了具体的布局后进行Grid布局分割:具体分割的方法和原来在移动端没啥区别:下一篇就是控件的拖放了;最终简单的效果先这样吧;以后…

使用ABBYY FineReader进行自动图像预处理

2019独角兽企业重金招聘Python工程师标准>>> 扫描图像和数码照片中常见的扭曲文本行、歪斜、噪声和其他缺陷可能会降低识别质量&#xff0c;ABBYY FineReader可自动消除这些缺陷&#xff0c;也允许手动消除。 ABBYY FineReader有几个图像预处理功能&#xff0c;如果…

Avalonia跨平台入门第五篇之ListBox多选

前面我也提前预告了今天要实现的效果;不过中间被卡了一下;今天赶紧去弥补上次要做的效果,其实在WPF效果中已经实现过了,看效果吧:ListBox的前台布局代码:使用的附加属性和WPF好相似:子项模板(绑定写法简化了好多):多值转换器(少了一个ConvertBack):最终简单的效果先这样吧;以后…

Android之android.os.NewWorkOnMainThreadException解决办法

1、问题 用别人提供的的sdk的Demo出现android.os.NewWorkOnMainThreadException 2、解决办法 网络请求开启一个线程请求或者开启异步任务都行 3、总结 1、 之前就看到过这种android.os.NewWorkOnMainThreadException异常&#xff0c;时间很久了&#xff0c;自己也没反映过来&a…

金蝶K/3 WISE 12.3订单跟踪SQL报表

金蝶K3一直缺少完整的跟踪报表&#xff0c;所以我们开发了一张完整的跟踪报表&#xff0c;通过查询分析工具直接生成。代码&#xff08;WIN2008 R2SQL 2008 R2环境&#xff0c;K3 WISE 12.3&#xff09;&#xff1a;select t1.fname1 客户,t1.fname2 业务员,t1.f_102 款号,t1.f…

开源绘画应用 Pinta 已移植到GTK 3和.NET 6

Pinta [1]是一款开源绘画应用&#xff0c;适用于 Linux、Windows 和 macOS。你可以用它来进行自由手绘/素描。你也可以用它在现有的图片上添加箭头、方框、文字等。年初发布了 Pinta 2.0.2 版本&#xff0c;这是我看到的第一款桌面的dotnet6 和 gtksharp的 应用。Pinta是一个小…

Druid源码分析系列1:dataSource.init()的准备工作

2019独角兽企业重金招聘Python工程师标准>>> 本节&#xff0c;讲解 dataSource.init(); 打断点在 stop in com.alibaba.druid.pool.DruidDataSource.init 好&#xff0c;开始研究代码 public void init() throws SQLException {// 首先确定没有initedif (inited) {r…

软件测试推荐专业,软件测试专业老师推荐信

尊敬的领导&#xff1a;您好&#xff01;首先感谢您在百忙之中抽出时间来阅读我学生XX的推荐信&#xff01;该生是XX大学软件测试专业应届毕业生&#xff0c;自进入XX大学以来&#xff0c;凭借自身扎实的基础和顽强拼搏的奋斗精神&#xff0c;经过几年不断的学习&#xff0c;在…