文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何在 .NetCore 中使用 AutoMapper 高级功能

2024-12-03 13:33

关注

本文转载自微信公众号「码农读书」,作者码农读书。转载本文请联系码农读书公众号。

AutoMapper 是一个基于约定的面向对象的映射器,它的功能常用于将一个 input 对象 转成一个不同类型的 output 对象,input 和 output 对象之间的属性可能相同也可能不相同,这一篇我们来一起研究一下 AutoMapper 的一些高级玩法。

安装 AutoMapper

要想在项目中使用 AutoMapper ,需要通过 nuget 引用 AutoMapper 和 AutoMapper.Extensions.Microsoft.DependencyInjection 包,可以通过 Visual Studio 2019 的 NuGet package manager 可视化界面安装 或者 通过 NuGet package manager 命令行工具输入以下命令:

  1. Install-Package AutoMapper 
  2. Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection 

配置 AutoMapper

一旦 AutoMapper 成功安装之后,接下来就可以将它引入到 ServiceCollection 容器中,如下代码所示:

  1. public void ConfigureServices(IServiceCollection services) 
  2.         {          
  3.             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); 
  4.  
  5.             services.AddAutoMapper(typeof(AuthorProfile)); 
  6.         } 

使用 profiles 统一管理 mapping 信息

可以使用 profiles 来统一组织你的 mapping 信息,要创建 profile,需要实现 AutoMapper 提供的 Profile 类,然后在你刚才创建的 Profile 子类的构造函数中添加映射信息,下面的代码展示了如何创建一个从 Proifle 继承的 AuthorProfile 类以及相关信息。

  1. public class AuthorProfile : Profile 
  2.      public AuthorProfile() 
  3.      { 
  4.          CreateMap(); 
  5.      } 

接下来再看 AuthorModel 和 AuthorDTO 两个对象的定义:

  1. public class AuthorModel 
  2.    { 
  3.        public int Id 
  4.        { 
  5.            get; set
  6.        } 
  7.        public string FirstName 
  8.        { 
  9.            get;set
  10.        } 
  11.        public string LastName 
  12.        { 
  13.            get; set
  14.        } 
  15.        public string Address 
  16.        { 
  17.            get; set
  18.        } 
  19.    } 
  20.  
  21.    public class AuthorDTO 
  22.    { 
  23.        public int Id 
  24.        { 
  25.            get; set
  26.        } 
  27.        public string FirstName 
  28.        { 
  29.            get; set
  30.        } 
  31.        public string LastName 
  32.        { 
  33.            get; set
  34.        } 
  35.        public string Address 
  36.        { 
  37.            get; set
  38.        } 

使用 ReverseMap()

值得注意的是,上面的示例是一种 单向流动,这是什么意思呢?举个例子吧,下面是 单向流动 的一段代码。

  1. AutoMapper.Mapper.CreateMap(); 

有了这个 Map,接下来就可以轻松实现 AuthorDTO 到 AuthorModel 的转换,代码如下:

  1. var authorModel = AutoMapper.Mapper.Map(author); 

假设因为某种原因,你需要将 authorModel 实例反转成 authorDTO,这时你用了如下的代码段。

  1. var author = AutoMapper.Mapper.Map(authorModel); 

很遗憾,这种方式注定会抛出异常,这是因为 AutoMapper 并不知道如何实现 authorModel 到 authorDTO 的转换,毕竟你没有定义此种 map 的映射流向,那怎么解决呢?可以再定义一个 CreateMap 映射哈,其实没必要,简单粗暴的做法就是调用 ReverseMap 即可,实现代码如下:

  1. AutoMapper.Mapper.CreateMap().ReverseMap(); 

使用 ForMember() 和 MapFrom()

这一节我们继续使用之前说到的 AuthorModel 和 AuthorDTO 类,下面的代码片段展示了如何将 AuthorModel 转成 AuthorDTO 。

  1. var author = new AuthorModel();            
  2. author.Id = 1; 
  3. author.FirstName = "Joydip"
  4. author.LastName = "Kanjilal"
  5. author.Address = "Hyderabad"
  6. var authorDTO = _mapper.Map(author); 

现在假设我将 AuthorModel 中的 Address 改成 Address1,如下代码所示:

  1. public class AuthorModel 
  2.    { 
  3.        public int Id 
  4.        { 
  5.            get; set
  6.        } 
  7.        public string FirstName 
  8.        { 
  9.            get; set
  10.        } 
  11.        public string LastName 
  12.        { 
  13.            get; set
  14.        } 
  15.        public string Address1 
  16.        { 
  17.            get; set
  18.        } 
  19.    } 

然后在 AuthorProfile 中更新一下 mapping 信息,如下代码所示:

  1. public class AuthorProfile : Profile 
  2.     { 
  3.         public AuthorProfile() 
  4.         { 
  5.             CreateMap().ForMember(destination => destination.Address, map => map.MapFrom(source => source.Address1)); 
  6.         } 
  7.     } 

使用 NullSubstitute

何为 NullSubstitute 呢?大意就是在映射转换的过程中,将input 为null 的属性映射之后做自定义处理,比如在 ouput 中改成 No Data,下面的代码展示了如何去实现。

  1. AutoMapper.Mapper.CreateMap().ForMember(destination => destination.Address, opt => opt.NullSubstitute("No data")); 

mapping 的 AOP 拦截

考虑下面的两个类。

  1. public class OrderModel 
  2.  { 
  3.    public int Id { get; set; } 
  4.    public string ItemCode { get; set; } 
  5.    public int NumberOfItems { get; set; } 
  6.  } 
  7.  
  8.  public class OrderDTO 
  9.  { 
  10.    public int Id { get; set; } 
  11.    public string ItemCode { get; set; } 
  12.    public int NumberOfItems { get; set; } 
  13.  } 

可以使用 BeforeMap() 在 源对象 或者 目标对象 上执行一些计算或者初始化成员操作,下面的代码展示了如何去实现。

  1. Mapper.Initialize(cfg => { 
  2.   cfg.CreateMap().BeforeMap((src, dest) => src.NumberOfItems = 0) 
  3. }); 

当 mapping 执行完之后,可以在 目标对象 上 安插 AfterMap() 方法,下面的代码展示了如何去实现。

  1. public OrderDTO MapAuthor(IMapper mapper, OrderDTO orderDTO) 
  2.         { 
  3.             return mapper.Map(orderDTO, opt => 
  4.             { 
  5.                 opt.AfterMap((src, dest) => 
  6.                 { 
  7.                     dest.NumberOfItems = _orderService.GetTotalItems(src); 
  8.                }); 
  9.             }); 
  10.         } 

使用嵌套映射

AutoMapper 同样也可以使用嵌套映射,考虑下面的 domain 类。

  1. public class Order 
  2.     { 
  3.         public string OrderNumber { get; set; } 
  4.         public IEnumerable OrderItems { get; set; } 
  5.     } 
  6.  
  7.     public class OrderItem 
  8.     { 
  9.         public string ItemName { get; set; } 
  10.         public decimal ItemPrice { get; set; } 
  11.         public int ItemQuantity { get; set; } 
  12.     } 

接下来再看一下 DTO 类。

  1. public class OrderDto 
  2.     { 
  3.         public string OrderNumber { get; set; } 
  4.         public IEnumerable OrderItems { get; set; } 
  5.     } 
  6.  
  7.     public class OrderItemDto 
  8.     { 
  9.         public string ItemName { get; set; } 
  10.         public decimal ItemPrice { get; set; } 
  11.         public int ItemQuantity { get; set; } 
  12.     } 

最后看看如何在转换的过程中使用 mapping 的。

  1. var orders = _repository.GetOrders(); 
  2. Mapper.CreateMap<Order, OrderDto>(); 
  3. Mapper.CreateMap(); 
  4. var model = Mapper.MapOrder>, IEnumerable>(orders); 

AutoMapper 让你用最小化的配置实现了对象之间的映射,同时也可以实现自定义的解析器来实现具有完全不同结构对象之间的映射,自定义解析器可以生成与目标对象具有相同结构的exchange,以便AutoMapper在运行时可以据其实现映射。

译文链接:https://www.infoworld.com/article/3406800/more-advanced-automapper-examples-in-net-core.html

 

来源:码农读书内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯