0

0

使用AutoMapper实现Dto和Model的自由转换(上)

巴扎黑

巴扎黑

发布时间:2016-12-20 11:28:46

|

1739人浏览过

|

来源于php中文网

原创

在实际的软件开发项目中,我们的“业务逻辑”常常需要我们对同样的数据进行各种变换。例如,一个web应用通过前端收集用户的输入成为dto,然后将dto转换成领域模型并持久化到数据库中。另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转换成dto再呈现给用户。有时候我们还会面临更多的数据使用需求,例如有多个数据使用的客户端,每个客户端都有自己对数据结构的不同需求,而这也需要我们进行更多的数据转换。 
频繁的数据转换琐碎而又凌乱,很多时候我们不得不: 
(1)在两个类型几乎只是名字不同而结构大体相似,却只能以手工的、逐个属性赋值的方式实现数据在类型间的“传递”。 
(2)每遇到一个新的数据转换场景就手动实现一套转换逻辑,导致数据转换操作重复而又分散到应用的各个角落。 
如果有这样一个“变形金刚”般的工具,把“橘子”变成我们想要的“苹果”,而我们需要做的只是定义好转换规则——做我们真正的业务逻辑,或者甚至在简单场景下连规则都不需要定义(convention over configuration),那将会是非常美好的事情。事实上在.net中我们不用重复发明轮子,因为我们有——automapper,一个强大的object-object mapping工具。 
好吧,我承认自己有一点小小的激动,事实上我所做的项目正在经历以上的“困惑”,而automapper确实带给我眼前一亮的感觉。因此我花了一点周末休息时间小小尝试了一把automapper,通过做小的应用场景实现dto到领域模型的映射,确实感觉到了它的“强大气场”。我将在文章中分享自己的使用心得,希望能给同样处于困惑中的你带来一点帮助。完整的项目代码我会在晚一些时候发布到自己的git repository中,欢迎大家自由参考使用。 
【一】 应用场景说明 
先来看看我所”虚拟“的领域模型。这一次我定义了一个书店(bookstore): 

C#代码  

public class BookStore  

{  

    public string Name { get; set; }  

    public List Books { get; set; }  

    public Address Address { get; set; }  

}  


书店有自己的地址(Address): 

C#代码  

public class Address  

{  

    public string Country { get; set; }  

网趣购物系统精装版
网趣购物系统精装版

精装版对原程序进行了大量的更新和调整,在安全性和实用性上均有重大突破,特色功能:完美整合支付宝功能,根据用户需求,并具有打开和关闭支付宝的功能!匿名用户购买功能,商城支持匿名直接购买商品功能,方便用户购物!增加了后台LOGO图片上传管理功能,管理简单、易用对广告管理进行扩充,所有广告图片、FLASH均可实现在线上传管理!多种在线支付方式,程序同时支持网银、西部支付,可自由选择切换!支持简繁互换显示

下载

    public string City { get; set; }  

    public string Street { get; set; }  

    public string PostCode { get; set; }  

}  


同时书店里放了n本书(Book): 

C#代码  

public class Book  

{  

    public string Title { get; set; }  

    public string Description { get; set; }  

    public string Language { get; set; }  

    public decimal Price { get; set; }  

    public List Authors { get; set; }  

    public DateTime? PublishDate { get; set; }  

    public Publisher Publisher { get; set; }  

    public int? Paperback { get; set; }  

}  


每本书都有出版商信息(Publisher): 

C#代码  

public class Publisher  

{  

    public string Name { get; set; }  

}  


每本书可以有最多2个作者的信息(Author): 

C#代码  

public class Author  

{  

    public string Name { get; set; }  

    public string Description { get; set; }  

    public ContactInfo ContactInfo { get; set; }  

}  


每个作者都有自己的联系方式(ContactInfo): 

C#代码  

public class ContactInfo  

{  

    public string Email { get; set; }  

    public string Blog { get; set; }  

    public string Twitter { get; set; }  

}  


差不多就是这样了,一个有着层级结构的领域模型。 
再来看看我们的Dto结构。 
在Dto中我们有与BookStore对应的BookStoreDto: 

C#代码  

public class BookStoreDto  

{  

    public string Name { get; set; }  

    public List Books { get; set; }  

    public AddressDto Address { get; set; }  

}  


其中包含与Address对应的AddressDto: 

C#代码  

public class AddressDto  

{  

    public string Country { get; set; }  

    public string City { get; set; }  

    public string Street { get; set; }  

    public string PostCode { get; set; }  

}  


以及与Book相对应的BookDto: 

C#代码  

public class BookDto  

{  

    public string Title { get; set; }  

    public string Description { get; set; }  

    public string Language { get; set; }  

    public decimal Price { get; set; }  

    public DateTime? PublishDate { get; set; }  

    public string Publisher { get; set; }  

    public int? Paperback { get; set; }  

    public string FirstAuthorName { get; set; }  

    public string FirstAuthorDescription { get; set; }  

    public string FirstAuthorEmail { get; set; }  

    public string FirstAuthorBlog { get; set; }  

    public string FirstAuthorTwitter { get; set; }  

    public string SecondAuthorName { get; set; }  

    public string SecondAuthorDescription { get; set; }  

    public string SecondAuthorEmail { get; set; }  

    public string SecondAuthorBlog { get; set; }  

    public string SecondAuthorTwitter { get; set; }  

}  


注意到我们的BookDto”拉平了“整个Book的层级结构,一个BookDto里携带了Book及其所有Author、Publisher等所有模式的数据。 
正好我们来看一下Dto到Model的映射规则。 
(1)BookStoreDto -> BookStore 

BookStoreDto中的字段    BookStore中的字段    

Name    Name    

Books    Books    

Address    Address    


(2)AddressDto -> Address 

AddressDto中的字段    Address中的字段    

Country    Country    

City    City    

Street    Street    

PostCode    PostCode    


(3)BookDto -> Book。 
BookDto中的一些基本字段可以直接对应到Book中的字段。 

BookDto中的字段    Book中的字段    

Title    Title    

Description    Description    

Language    Language    

Price    Price    

PublishDate    PublishDate    

Paperback    Paperback    


每本书至多有2个作者,在BookDto中分别使用”First“前缀和”Second“前缀的字段来表示。因此,所有FirstXXX字段都将映射成Book的Authors中的第1个Author对象,而所有SecondXXX字段则将映射成Authors中的第2个Author对象。 

BookDto中的字段    Book中的Authors中的第1个Author对象中的字段    

FirstAuthorName    Name    

FirstAuthorDescription    Description    

FirstAuthorEmail    ContactInfo.Email    

FirstAuthorBlog    ContactInfo.Blog    

FirstAuthorTwitter    ContactInfo.Twitter    


注意上表中的ContactInfo.Email表示对应到Author对象的ContactInfo的Email字段,依次类推。类似的我们有: 

BookDto中的字段    Book中的Authors中的第2个Author对象中的字段    

SecondAuthorName    Name    

SecondAuthorDescription    Description    

SecondAuthorEmail    ContactInfo.Email    

SecondAuthorBlog    ContactInfo.Blog    

SecondAuthorTwitter    ContactInfo.Twitter    


最后还有Publisher字段,它将对应到一个独立的Publisher对象。 

BookDto中的字段    Publisher中的字段    

Publisher    Name    


差不多就是这样了,我们的需求是要实现这一大坨Dto到另一大坨的Model之间的数据转换。

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

99

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

132

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

15

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

63

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7.5万人学习

C 教程
C 教程

共75课时 | 4.2万人学习

C++教程
C++教程

共115课时 | 13.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号