注:本系列文章的代码可以在
这里下载。
在实际的软件开发项目中,我们的“业务逻辑”常常需要我们对同样的数据进行各种变换。例如,一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中。另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转换成Dto再呈现给用户。有时候我们还会面临更多的数据使用需求,例如有多个数据使用的客户端,每个客户端都有自己对数据结构的不同需求,而这也需要我们进行更多的数据转换。
频繁的数据转换琐碎而又凌乱,很多时候我们不得不:
(1)在两个类型几乎只是名字不同而结构大体相似,却只能以手工的、逐个属性赋值的方式实现数据在类型间的“传递”。
(2)每遇到一个新的数据转换场景就手动实现一套转换逻辑,导致数据转换操作重复而又分散到应用的各个角落。
如果有这样一个“变形金刚”般的工具,把“橘子”变成我们想要的“苹果”,而我们需要做的只是定义好转换规则——做我们真正的业务逻辑,或者甚至在简单场景下连规则都不需要定义(Convention Over Configuration),那将会是非常美好的事情。事实上在.NET中我们不用重复发明轮子,因为我们有——AutoMapper,一个强大的Object-Object Mapping工具。
好吧,我承认自己有一点小小的激动,事实上我所做的项目正在经历以上的“困惑”,而AutoMapper确实带给我眼前一亮的感觉。因此我花了一点周末休息时间小小尝试了一把AutoMapper,通过做小的应用场景实现Dto到领域模型的映射,确实感觉到了它的“强大气场”。我将在文章中分享自己的使用心得,希望能给同样处于困惑中的你带来一点帮助。完整的项目代码我会在晚一些时候发布到自己的git repository中,欢迎大家自由参考使用。
【一】 应用场景说明
先来看看我所”虚拟“的领域模型。这一次我定义了一个书店(BookStore):
public class BookStore
{
public string Name { get; set; }
public List<Book> Books { get; set; }
public Address Address { get; set; }
}
书店有自己的地址(Address):
public class Address
{
public string Country { get; set; }
public string City { get; set; }
public string Street { get; set; }
public string PostCode { get; set; }
}
同时书店里放了n本书(Book):
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<Author> Authors { get; set; }
public DateTime? PublishDate { get; set; }
public Publisher Publisher { get; set; }
public int? Paperback { get; set; }
}
每本书都有出版商信息(Publisher):
public class Publisher
{
public string Name { get; set; }
}
每本书可以有最多2个作者的信息(Author):
public class Author
{
public string Name { get; set; }
public string Description { get; set; }
public ContactInfo ContactInfo { get; set; }
}
每个作者都有自己的联系方式(ContactInfo):
public class ContactInfo
{
public string Email { get; set; }
public string Blog { get; set; }
public string Twitter { get; set; }
}
差不多就是这样了,一个有着层级结构的领域模型。
再来看看我们的Dto结构。
在Dto中我们有与BookStore对应的BookStoreDto:
public class BookStoreDto
{
public string Name { get; set; }
public List<BookDto> Books { get; set; }
public AddressDto Address { get; set; }
}
其中包含与Address对应的AddressDto:
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:
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之间的数据转换。
分享到:
相关推荐
在本篇中,我们将深入探讨如何使用AutoMapper库在.NET应用程序中实现Data Transfer Objects (Dto)与业务模型之间的自由转换。AutoMapper是一个流行的开源库,它简化了对象之间的映射过程,大大减少了手动编写转换...
在实际项目中,我们经常需要将Dto对象转换为实体类,反之亦然,这时就引入了自动化映射工具——AutoMapper。 AutoMapper是一个强大的.NET库,它简化了对象到对象之间的映射过程。在没有AutoMapper的情况下,开发者...
在.NET开发领域,Entity Framework(简称EF)是微软提供的一款强大的对象关系映射(ORM)框架,它允许开发者使用面向对象的...在实际项目中,这样的设计模式和实现方式对于构建可扩展且易于维护的软件架构至关重要。
6. **DTO(Data Transfer Objects)**:在ASP.NET MVC或Web API中,通常使用DTO作为控制器与视图或客户端之间的数据交换格式,AutoMapper可以帮助轻松实现业务对象与DTO之间的转换。 7. **性能优化**:通过缓存映射...
在了解了 DTO 的概念后,我们可以使用 AutoMapper 实现 DTO 和领域模型之间的转换。AutoMapper 是一个轻量级的 Object-Object Mapping 工具,非常流行且国外的大牛们都使用它。 使用 AutoMapper 有多种方式,下面是...
AutoMapper是一款强大的对象到对象映射库,广泛应用于.NET开发中,用于简化对象之间的...在实际的AutoMapperDemo项目中,你可以找到更多关于如何使用AutoMapper的实际示例,包括复杂的映射规则和多层嵌套对象的转换。
使用Condition方法可以实现条件映射。 AutoMapper还支持泛型类型映射,可以直接支持开放泛型类型映射,不需要创建封闭泛型类型。AutoMapper反射类型映射时支持类型转换。 嵌套类型映射实际上是相当于2对类型的映射...
3. **执行映射**:在实际业务逻辑中,当需要进行对象间的数据转换时,调用`Map()`方法,传入源对象和目标对象的实例,`AutoMapper`会根据之前定义的映射配置自动进行数据复制。 例如,假设我们有一个`UserEntity`...
4. **类型转换**:在映射过程中,AutoMapper可以自动处理源类型和目标类型之间的转换,只要.NET Framework提供了相应的转换器。 5. **双向映射**:不仅可以从实体到合同,也可以从合同到实体,只需定义一次映射规则...
在结合EF6使用时,AutoMapper.EF6扩展可以帮助我们在保存到数据库之前自动转换实体对象,简化数据处理。例如,当接收一个视图模型并将其保存到数据库时,可以这样配置: ```csharp Mapper.CreateMap, Entity>() ....
在`Get`方法中,我们创建了一个`SourceClass`实例,并使用AutoMapper将其转换为`DestinationClass`。 总结一下,ASP.NET 6集成AutoMapper的主要步骤包括:安装AutoMapper相关包,定义映射规则,注册配置,以及在...
在这个例子中,`ProjectTo`方法将数据库中的`User`实体转换为DTO(数据传输对象),同时应用了之前定义的映射规则和动态条件。 5. **优化映射性能**:在处理大量数据时,应考虑使用`BatchMapper.Map`或`ProjectTo`...
标题 "10.3 AutoMapper" 指向的是关于 AutoMapper 的一个特定章节,这是一款...综上所述,AutoMapper 是 .NET 开发中的强大工具,简化了对象之间的数据转换。正确地配置和使用它可以极大地提高代码的可读性和可维护性。
这时,我们可以使用Automapper来帮助我们完成类型转换。 首先,我们需要安装Automapper的Nuget包。在Visual Studio中,我们可以通过 Tools - Nuget Package Manager - Package Manager Console输入Install-Package ...
标题中的“automapper+autofac+mvc5+三层-ioc”揭示了这个项目或教程是关于使用四个关键技术和框架来构建一个三层架构的MVC应用程序。这些技术包括: 1. AutoMapper:AutoMapper 是一个对象对象映射库,用于.NET...
2. **降低耦合**:通过使用DTO,客户端和服务端之间的耦合度被大大降低,因为它们只需要关注DTO的结构,而无需关心具体的业务逻辑。 3. **提高效率**:相比于多次调用服务端接口获取数据,使用DTO可以在一次调用中...
SqlSugarCore是一款高效、轻量级的.NET Core数据库操作库,它提供了丰富的ORM(对象关系映射)功能,...在实际项目中,根据具体需求和场景,合理地使用和配置这两个工具,将有助于打造高效且易于维护的数据库解决方案。
总的来说,AutoMapper在DDD中扮演着重要角色,它使得在领域模型和DTO之间进行数据转换变得更加高效和方便,从而促进了安全且高效的跨层通信。在进行领域驱动设计时,合理利用AutoMapper可以显著提高代码的可维护性和...