一. 使用意圖 常常在開發過程中,碰到一個實體上的屬性值,要賦值給另外一個相類似實體屬性時,且屬性有很多的情況。一般不利用工具的話,就要實例化被賦值實體B,然後再將實體A的欄位一個個賦值給B的屬性,單單寫這些沒有技術含量的賦值語句,就要用很大的代碼篇幅。假如做得好一點的話,一般就是利用反射的方式,將 ...
一. 使用意圖
常常在開發過程中,碰到一個實體上的屬性值,要賦值給另外一個相類似實體屬性時,且屬性有很多的情況。一般不利用工具的話,就要實例化被賦值實體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
從我開發過程使用到一些場景
- 實體->實體
- 集合->集合
- 實體欄位名稱不同
- 實體數據類型不同
- 相同名稱,相同數據類型無需配置
- 有Queryable Extensions ,也即支持Entity Framework
三. 最佳實踐
AutoMapper開髮指南,有詳細的介紹,我這裡就不再搬過說了,大家有空自己研究研究,我這裡主要介紹一下AutoMapper比較好的實踐方式,廢話不多說,直接做項目給大家看。
- 項目結構
每個項目用途,解決方案文件夾基本標示清楚。
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);
}
}
}
經過追蹤對象屬性變化,全部轉換成功,不方便截圖,稍後我會放出源代碼。
最後源代碼: