訪問數據庫、IPC 通信、業務模型、視圖模型……對于同一個業務的同一種數據,經常會使用多種數據模型工作在不同的代碼模塊中。這時它們之間的互相轉換便是大量的重復代碼了。
使用 AutoMapper 便可以很方便地在不同的模型之間進行轉換而減少編寫太多的轉換代碼(如果這一處的代碼對性能不太敏感的話)。
關于 AutoMapper 的系列文章:
安裝 AutoMapper 庫
這是 AutoMapper 的官方 GitHub 倉庫:
安裝 AutoMapper 的 NuGet 包即可在項目中使用 AutoMapper。
入門
以下是一個最簡單的控制臺演示程序的代碼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // Program.cs
var mapper = InitializeMapper();var dao = new Walterlv1Dao
{Id = "2ed3558ac938438fb2c1d2de71d7bb90",Name = "walterlv",Text = "blog.walterlv.com",
};
var vo = mapper.Map<Walterlv1Vo>(dao);
Console.WriteLine($"Name = {vo.Name}, Text = {vo.Text}");static IMapper InitializeMapper()
{var configuration = new MapperConfiguration(cfg =>{cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>();});
#if DEBUGconfiguration.AssertConfigurationIsValid();
#endifvar mapper = configuration.CreateMapper();return mapper;
}
|
在這段代碼中:
我們定義了一個方法 InitializeMapper,在里面初始化 IMapper 的新實例。
初始化?MapperConfiguration,定義類型的映射關系
在?DEBUG?下驗證?MapperConfiguration?的映射是否正確
創建一個?IMapper?的映射器,用于后續映射使用
我們初始化了一個?Walterlv1Dao?類的實例
我們調用?mapper.Map?將其映射到?Walterlv1Vo?類型
這兩個類型的定義如下(雖然無關緊要)。
1
2
3
4
5
6
7
8
9
10
11
12
| public class Walterlv1Dao
{public string? Id { get; set; }public string? Name { get; set; }public string? Text { get; set; }
}
public class Walterlv1Vo
{public string? Id { get; set; }public string? Name { get; set; }public string? Text { get; set; }
}
|
如果你的應用程序中會使用到依賴注入,那么只需要把拿到的 IMapper 加入即可。
如果希望兩個類型之間能夠雙向映射,那么在初始化 IMapper 的時候也應該再額外調用一下 ReverseMap 方法,否則就會拋出異常 AutoMapper.AutoMapperMappingException:“Missing type map configuration or unsupported mapping.”。
1
| cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>().ReverseMap();
|
復雜類型和集合
現在,我們讓模型稍復雜一些:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| public class Walterlv1Dao
{public string? Id { get; set; }public string? Name { get; set; }public FriendDao? Friend { get; set; }
}
public class FriendDao
{public string? Id { get; set; }public string? Name { get; set; }
}
public class Walterlv1Vo
{public string? Id { get; set; }public string? Name { get; set; }public FriendVo? Friend { get; set; }
}
public class FriendVo
{public string? Id { get; set; }public string? Name { get; set; }
}
|
AutoMapper 能處理這樣的屬性嵌套情況,只需要設置嵌套類型也能映射即可:
1
2
| cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>().ReverseMap();
cfg.CreateMap<FriendDao, FriendVo>().ReverseMap();
|
如果兩個模型中子模型的類型是一樣的,那么只會進行簡單的賦值,而不會創建新的對象。
例如上面例子里,如果 FriendDao 和 FriendVo 合并成 Friend 類型,兩個類型都使用這個合并的類型,那么映射之后,Friend 將是同一個對象。
除了復雜類型,列表也是可以的:
1
2
3
4
5
6
7
8
9
10
11
12
| public class Walterlv1Dao
{public string? Id { get; set; }public string? Name { get; set; }public List<FriendDao>? Friend { get; set; }
}
public class Walterlv1Vo
{public string? Id { get; set; }public string? Name { get; set; }public List<FriendVo>? Friend { get; set; }
}
|
參考資料