AutoMapper 使用实践

一. 使用意图

常常在开发过程中,碰到一个实体上的属性值,要赋值给另外一个相类似实体属性时,且属性有很多的情况。一般不利用工具的话,就要实例化被赋值实体B,然后再将实体A的字段一个个赋值给B的属性,单单写这些没有技术含量的赋值语句,就要用很大的代码篇幅。假如做得好一点的话,一般就是利用反射的方式,将A属性赋值给B,当然用反射的话,要顺利将A的属性,赋值B的属性,这样确实能够减少代码篇幅,那就要有一些约束或者限制,例如属性名称要相同,属性的数据类型要相同,这样反射起来才不费力。那如何使反射起来,更加灵活,可配置,且配置和反射过程能够分离,实现职责单一,AutoMapper 就是这样一个开源类库。

二. 认识AutoMapper

官方地址 :http://automapper.org/

GitHub 地址:https://github.com/AutoMapper/AutoMapper 包含AutoMapper 源代码与应用Simple。

开发指南:https://github.com/AutoMapper/AutoMapper/wiki/Getting-started

从我开发过程使用到一些场景

  1. 实体->实体
  2. 集合->集合
  3. 实体字段名称不同
  4. 实体数据类型不同
  5. 相同名称,相同数据类型无需配置
  6. 有Queryable Extensions ,也即支持Entity Framework

三. 最佳实践

AutoMapper开发指南,有详细的介绍,我这里就不再搬过说了,大家有空自己研究研究,我这里主要介绍一下AutoMapper比较好的实践方式,废话不多说,直接做项目给大家看。

  1. 项目结构

每个项目用途,解决方案文件夹基本标示清楚。

2. 以订单为例(不是真实业务,只是举个简单的例子),在Models 实体类库 新增OrderModel模型,在ViewModels 新增OrderViewModel模型,代码在下面

using System;namespace Models
{    public class OrderModel
    {        public Guid OrderGuid { get; set; }        public string OrderNo { get; set; }        public string OrderCreator { get; set; }        public DateTime OrderDateTime { get; set; }        public string OrderStatus { get; set; }        public string Description { get; set; }        public string Creator { get; set; }        public DateTime CreateDateTime { get; set; }        public string LastModifier { get; set; }        public DateTime LastModifiedDateTime { get; set; }
    }
}
using System;namespace ViewModels
{    public class OrderViewModel
    {        public Guid OrderGuid { get; set; }        public string OrderNo { get; set; }        public string OrderCreator { get; set; }        public DateTime OrderDateTime { get; set; }        public string OrderStatus { get; set; }        public string Description { get; set; } 
    }
}

这里假设ViewModel,在使用过程中,不需要创建与修改相关的字段。

3. AutoMapper 配置

通过NuGet 程序包管理器,下载AutoMapper Dll,右键-》AutoMapperProfiles 类库-》管理NuGet程序包-》联机-》右上角搜索“AutoMapper” 下载安装

新增 ModelToViewModelProfile,ViewModelToModelProfile 两个配置类,继承AutoMapper 的 Profile 类,实现Configure重载方法,并分别引入Models & ViewModels 类库,ModelToViewModelProfile,ViewModelToModelProfile 代码如下

using AutoMapper;using Models;using ViewModels;namespace AutoMapperProfiles
{    public class ModelToViewModelProfile:Profile
    {        protected override void Configure()
        {
            CreateMap<OrderModel, OrderViewModel>();
        }
    }
}
using AutoMapper;using Models;using ViewModels;namespace AutoMapperProfiles
{    public class ViewModelToModelProfile : Profile
    {        protected override void Configure()
        {
            CreateMap<OrderViewModel, OrderModel>();
        }
    }
}

4.注册配置

在AutoMapperRegister 项目中,新增AutoMapperProfileRegister 类,按照 第3点,安装一下AutoMapper,同时引用AutoMapperProfiles 类库。代码如下

using AutoMapper;using AutoMapperProfiles;namespace AutoMapperRegister
{    public class AutoMapperProfileRegister
    {        public static void Register()
        {
            Mapper.Configuration.AddProfile(new ModelToViewModelProfile());
            Mapper.Configuration.AddProfile(new ViewModelToModelProfile());
        }
    }
}

5. 控制台验证是否能够顺利转换

按照 第3点,安装一下AutoMapper,引入 AutoMapperRegister ,Models,ViewModels Dll,编写测试代码,代码如下(见证奇迹的时候到了)

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using AutoMapper;using AutoMapperRegister;using Models;using ViewModels;namespace ConsoleAutoMapperSample
{    class Program
    {        static void Main(string[] args)
        {
            AutoMapperProfileRegister.Register();            var order = new OrderModel
                            {
                                OrderGuid = Guid.NewGuid(),
                                OrderNo = "201604020001",
                                OrderCreator = "david",
                                OrderDateTime = DateTime.Now,
                                OrderStatus = "已出库",
                                Description = "请提供个人发票"
                            };            var orderView = Mapper.Map<OrderModel, OrderViewModel>(order);
            orderView.OrderStatus = "已完成";            var updateOrder = Mapper.Map<OrderViewModel, OrderModel>(orderView);
        }
    }
}

经过追踪对象属性变化,全部转换成功,不方便截图,稍后我会放出源代码。

最后源代码:

http://files.cnblogs.com/files/davidzhou/AutoMapperSample.zip

原文发布于微信公众号 - 我为Net狂(dotNetCrazy)

原文发表时间:2016-04-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

Roslyn 入门:使用 .NET Core 版本的 Roslyn 编译并执行跨平台的静态的源码

发布于 2018-05-25 13:24 更新于 2018-06...

691
来自专栏菩提树下的杨过

silverlight获取外部数据的另一种选择:FluorineFx

Silverlight从其它系统获取外部数据的常规途径无非下面2种: 1、直接远程加载文本或xml文件 (直接请求ashx/aspx,然后在ashx/aspx上...

1955
来自专栏张善友的专栏

Reactive框架:简化异步及事件驱动编程

NET的Reactive Extensions包含一系列扩展方法和为.NET 4及Silverlight 4中新加入的 IObservable<out T> 和...

2238
来自专栏张善友的专栏

Entity Framework 4 的 POCO学习

Entity Framework 4的特性介绍可看这篇文章 .NET 4中Entity Framework简介,其中最感兴趣的一点就是对POCO的支持了:EF4...

2288
来自专栏cmazxiaoma的架构师之路

C#学习之路(1)--数据库技术

2124
来自专栏iOS122-移动混合开发研究院

【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类

背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题。我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题。视图和控制器相关的内存泄...

2626
来自专栏Spark学习技巧

kafka源码系列之mysql数据增量同步到kafka

2143
来自专栏walterlv - 吕毅的博客

C#/.NET 中的契约

发布于 2017-12-20 15:04 更新于 2018-04...

741
来自专栏王清培的专栏

.NET框架设计(高级框架架构模式)—钝化程序、逻辑冻结、冻结程序的延续、瞬间转移

阅读目录: 1.开篇介绍 2.程序书签(代码书签机制) 2.1ProgramBookmark 实现(使用委托来锚点代码书签) 2.2ProgramBookma...

22610
来自专栏领域驱动设计DDD实战进阶

DDD实战进阶第一波(四):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架三)

上一篇文章我们讲了经典DDD架构对比传统三层架构的优势,以及经典DDD架构每一层的职责后,本篇文章将介绍基础结构层中支持DDD的轻量级框架的主要代码。 这里需要...

5885

扫码关注云+社区

领取腾讯云代金券