AutoMapper在ABP框架中的使用说明

为了说明AutoMapper如何使用,我专门开设了一个专题来讲,如果您还没有查看该专题,请点击这里。既然系统地学习了AutoMapper,那么接下来就是该用它实战的时候了。今天,我们就来揭开AutoMapper如何在ABP框架中使用的面纱。

因为这里演示的是用ABP框架搭建的项目,本博客的讲解的前提是假设你有了ABP基础,所以,如果您还不了解ABP框架,请查看我的ABP框架的系列博客,请点击这里

下面正式开始今天的讲解。

首先,让我们稍微回忆一下AutoMapper的知识点。

问:什么是AutoMapper?

答:AutoMapper翻译过来就是“自动映射工具”。它的作用就是将一个源类型映射成一个目标类型,比如Person——>PersonDto,User——>UserDto。

问:什么情况下使用AutoMapper?

答:一般在项目的开发中,经常需要将Entity实体映射成ModelDto或者ViewModel,这个时候,使用AutoMapper仅需要简单的配置,就可以实现这些需求,非常方便。

接下来,讲一下项目中的具体配置。

在我的ABP项目中,首先核心层有一个实体类TerminalDevices,类定义如下:

  1 namespace Noah.ChargeStation.Core.Entities
  2 {
  3     //终端表
  4     public class TerminalDevices : Entity
  5     {
  6 
  7         /// <summary>
  8         /// 终端编码
  9         /// </summary>
 10         public virtual string Code
 11         {
 12             get;
 13             set;
 14         }
 15         /// <summary>
 16         /// IMEI
 17         /// </summary>
 18         public virtual string IMEI
 19         {
 20             get;
 21             set;
 22         }
 23         /// <summary>
 24         /// SIMCardNO
 25         /// </summary>
 26         public virtual string SIMCardNO
 27         {
 28             get;
 29             set;
 30         }
 31         /// <summary>
 32         /// InstallDate
 33         /// </summary>
 34         public virtual DateTime? InstallDate
 35         {
 36             get;
 37             set;
 38         }
 39         /// <summary>
 40         /// PlacePosition
 41         /// </summary>
 42         public virtual string PlacePosition
 43         {
 44             get;
 45             set;
 46         }
 47         /// <summary>
 48         /// Version
 49         /// </summary>
 50         public virtual int? Version
 51         {
 52             get;
 53             set;
 54         }
 55         /// <summary>
 56         /// TotalCoins
 57         /// </summary>
 58         public virtual int TotalCoins
 59         {
 60             get;
 61             set;
 62         }
 63         /// <summary>
 64         /// CurrentBoxCoins
 65         /// </summary>
 66         public virtual int CurrentBoxCoins
 67         {
 68             get;
 69             set;
 70         }
 71         /// <summary>
 72         /// 最小计费单位
 73         /// </summary>
 74         public virtual int MinimumUnit
 75         {
 76             get;
 77             set;
 78         }
 79         /// <summary>
 80         /// 充电时长
 81         /// </summary>
 82         public virtual int ChargeTime
 83         {
 84             get;
 85             set;
 86         }
 87         /// <summary>
 88         /// MoneyBoxCapacity
 89         /// </summary>
 90         public virtual int? MoneyBoxCapacity
 91         {
 92             get;
 93             set;
 94         }
 95         /// <summary>
 96         /// 终端名称
 97         /// </summary>
 98         public virtual string Name
 99         {
100             get;
101             set;
102         }
103         /// <summary>
104         /// 终端类型:0--同城类终端 1--跨城类终端
105         /// </summary>
106         public virtual int? Type
107         {
108             get;
109             set;
110         }
111         /// <summary>
112         /// 所属城市
113         /// </summary>
114         public virtual int? CityID
115         {
116             get;
117             set;
118         }
119         /// <summary>
120         /// 所属运营商
121         /// </summary>
122         public virtual int? OperatorID
123         {
124             get;
125             set;
126         }
127         /// <summary>
128         /// 所属站台
129         /// </summary>
130         public virtual int? StationID
131         {
132             get;
133             set;
134         }
135         /// <summary>
136         /// 经度
137         /// </summary>
138         public virtual decimal? Longitude
139         {
140             get;
141             set;
142         }
143         /// <summary>
144         /// 纬度
145         /// </summary>
146         public virtual decimal? Latitude
147         {
148             get;
149             set;
150         }
151         /// <summary>
152         /// 支付宝二维码内容
153         /// </summary>
154         public virtual string AlipayEWMContent
155         {
156             get;
157             set;
158         }
159         /// <summary>
160         /// 支付宝二维码图片
161         /// </summary>
162         public virtual string AlipayEWMImage
163         {
164             get;
165             set;
166         }
167         /// <summary>
168         /// 微信二维码内容
169         /// </summary>
170         public virtual string WechatEWMContent
171         {
172             get;
173             set;
174         }
175         /// <summary>
176         /// 微信二维码图片
177         /// </summary>
178         public virtual string WechatEWMImage
179         {
180             get;
181             set;
182         }
183         /// <summary>
184         /// 正在充电数量
185         /// </summary>
186         public virtual int? ChargingNum
187         {
188             get;
189             set;
190         }
191         /// <summary>
192         /// 上次通讯时间
193         /// </summary>
194         public virtual DateTime? LastConnectTime
195         {
196             get;
197             set;
198         }
199         /// <summary>
200         /// 0--失联 1--正常 2--维修 3--维护4--下线
201         /// </summary>
202         public virtual int? Status
203         {
204             get;
205             set;
206         }
207         /// <summary>
208         /// SystemCode
209         /// </summary>
210         public virtual string SystemCode
211         {
212             get;
213             set;
214         }
215         /// <summary>
216         /// Certificate
217         /// </summary>
218         public virtual string Certificate
219         {
220             get;
221             set;
222         }
223         /// <summary>
224         /// 到期时间
225         /// </summary>
226         public virtual DateTime? DueDate
227         {
228             get;
229             set;
230         }
231         /// <summary>
232         /// 创建人
233         /// </summary>
234         public virtual string CreatedBy
235         {
236             get;
237             set;
238         }
239         /// <summary>
240         /// 创建日期
241         /// </summary>
242         public virtual DateTime? CreatedDate
243         {
244             get;
245             set;
246         }
247         /// <summary>
248         /// 最后更新人
249         /// </summary>
250         public virtual string UpdatedBy
251         {
252             get;
253             set;
254         }
255         /// <summary>
256         /// 最后更新日期
257         /// </summary>
258         public virtual DateTime? UpdatedDate
259         {
260             get;
261             set;
262         }
263         public TerminalDevices()
264         {
265 
266         }
267 
268     }
269 
270 }
View Code

可以看到,仅一个实体类,就要将近300行的代码,但是在服务层或者展现层使用的时候,有些属性是不需要的,所以这时我们就要定义我们的Dto类了。

随后,我在ABP项目中的服务层定义了一个对应的TerminalDeviceDto类,定义如下:

 1 namespace Noah.ChargeStation.Application.TerminalDevicesApp.Dto
 2 {
 3     public class TerminalDeviceDto:IDto
 4     {
 5         [DisplayName("设备编码")]
 6         public string Code { get; set; }
 7         public string IMEI { get; set; }
 8         [DisplayName("SIM卡号")]
 9         public string SIMCardNO { get; set; }
10         public string InstallDate { get; set; }
11         public string PlacePosition { get; set; }
12         public int Version { get; set; }
13         [DisplayName("总投币")]
14         public int TotalCoins { get; set; }
15         public int CurrentBoxCoins { get; set; }
16         public int MinimumUnit { get; set; }
17         public int ChargeTime { get; set; }
18         public int MoneyBoxCapacity { get; set; }
19         public string Name { get; set; }
20         public int Type { get; set; }
21         public int CityId { get; set; }
22         public int OperatorId { get; set; }
23         public int StationId { get; set; }
24         public decimal Longitude { get; set; }
25         public decimal Latitude { get; set; }
26         public string AlipayEWMContent { get; set; }
27         public string AlipayEWMImage { get; set; }
28         public string WechatEWMContent { get; set; }
29         public string WechatEWMImage { get; set; }
30         public int ChargingNum { get; set; }
31         public DateTime LastConnectTime { get; set; }
32         public int Status { get; set; }
33         public string SystemCode { get; set; }
34         public string Certificate { get; set; }
35         public DateTime DueDate { get; set; }
36         public string CreatedBy { get; set; }
37         public DateTime CreatedDate { get; set; }
38         public string UpdatedBy { get; set; }
39         public DateTime UpdatedDate { get; set; }
40 
41     }
42 }
View Code

当然,这里的Dto类定义的属性跟你的具体业务相关,定义的属性还可能更少。

上面讲的是源类型和目标类型的定义,下面开始讲它们之间的映射配置。

首先,我在应用服务层新建一个文件夹取名“AutoMapper”,里面放跟AutoMapper配置相关的东西。

image

如图,新建一个类TerminalDeviceProfile(CityProfile类是我的另一个实体类对应的AutoMapper配置文件),定义如下:

namespace Noah.ChargeStation.Application.AutoMapper
{
    public class CityProfile:Profile
    {
        protected override void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Cities, CityDto>();
            });
        }
    }
}

如果您对这么配置不清楚原因,请查看我的AutoMapper系列教程,点击查看

再创建一个AutoMapperWebConfig静态类,定义如下:

namespace Noah.ChargeStation.Application.AutoMapper
{
    public static class AutoMapperWebConfig
    {
        public static void Configure()
        {
            Mapper.Initialize(cfg =>
            {
                cfg.AddProfile<CityProfile>();
                cfg.AddProfile<TerminalDeviceProfile>();
            });
            Mapper.AssertConfigurationIsValid();//验证所有的映射配置是否都正常
        }
    }
}

接下来,在应用服务层的模块类中调用该静态类的静态方法,加载所有的AutoMapper配置信息。

namespace Noah.ChargeStation.Application
{
    [DependsOn(typeof(ChargeStationCoreModule), typeof(AbpAutoMapperModule))]
    public class ChargeStationApplicationModule : AbpModule
    {
        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
            AutoMapperWebConfig.Configure();//一次性加载所有映射配置
        }
    }
}

这里需要注意的是,AutoMapper的配置一般放在项目启动的时候进行加载且只加载一次就够了,而在ABP框架搭建的项目中,除了展现层(Web和WebAPI层),其他层都会有一个Module类(类名以Module结尾)。这些类都重写了父类AbpModule的Initialize方法,旨在模块初始化的时候调用,这样,映射的配置也在模块初始化的时候完成了。如果在一般的ASP.Net项目中,应该在全局配置文件Global.asax中的Application_Start方法中调用AutoMapper的配置方法,其他项目类似。

以后,想要添加配置信息时,只需要定义相应的XXProfile类,然后在AutoMapperWebConfig类中添加配置文件类就可以了。

posted @ 2015-11-18 22:45 tkbSimplest 阅读(...) 评论(...) 编辑 收藏