0%

AutoMapper運用

寫網站常常會遇到從ViewModel對應到應用程式的DTO,或是DB的物件問題,以前自己的做法都是

```csharp public bool Login(LoginViewModel model) { Account account = new Account() { Account = model.Account, Password = model.Password } var Result = _AccountService.Loign(account ); return Result; }

public class LoginViewModel
{
public string Account{get;set;}
public string Password{get;set;}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62


等到內部運作完畢的時候可能又要把對應的DTO處理成ViewModel在拋回頁面,這種反覆一直寫的動作其實真的很煩人,直到最近同事介紹了[AutoMapper](https://www.nuget.org/packages/AutoMapper/)給我們之後,整個流程得到了大幅度的改善。

* AutoMapper的基本運用

當兩個物件的屬性都一樣時,AutoMapper會自動去對應並且轉出
[![](http://4.bp.blogspot.com/-j6G1kaI6BXw/VimtMro_B9I/AAAAAAAAHgY/qZYVfNriOm0/s1600/1.png)](http://4.bp.blogspot.com/-j6G1kaI6BXw/VimtMro_B9I/AAAAAAAAHgY/qZYVfNriOm0/s1600/1.png)

如果兩個物件的屬性對應略有不同,也可以加上規則

[![](http://1.bp.blogspot.com/-n04XweFHx5w/VimuRLyJtGI/AAAAAAAAHgg/H0pNXYnW11w/s1600/1.png)](http://1.bp.blogspot.com/-n04XweFHx5w/VimuRLyJtGI/AAAAAAAAHgg/H0pNXYnW11w/s1600/1.png)
* 如果兩的類別對應到同一個物件的情況
```csharp
void Main()
{
AccountViewModel model = new AccountViewModel() {
Account = "toyo",
Password = "pwd",
City = "Taipei",
District = "大安"
};
var Group = new Group() {
ID = 1,
Name = "客戶群組"
};
Mapper.CreateMap<AccountViewModel,AccountDTO>()
.ForMember(d=> d.Address , o=>o.MapFrom(s=>string.Concat(s.City,s.District))); var account = Mapper.Map<AccountDTO>(model);

//這邊用上面已經轉好的account,來接續Mapper
Mapper.CreateMap<Group, AccountDTO>()
.ForMember(d => d.Account, o => o.Ignore())
.ForMember(d => d.Password, o => o.Ignore())
.ForMember(d => d.Address, o => o.Ignore())
.ForMember(d => d.GroupName, o => o.MapFrom(s=>s.Name));
//注意
account = Mapper.Map<Group,AccountDTO>(Group,account);

account.Dump();
}

public class AccountViewModel
{
public string Account { get; set; }
public string Password { get; set; }
public string City { get; set; }
public string District {get;set;}
}

public class AccountDTO
{
public string Account { get; set; }
public string Password { get; set; }
public string Address { get; set; }
public string GroupName {get;set;}
}

public class Group{
public int ID { get; set; }
public string Name {get;set;}
}

結果

最後,在MVC的網站裡面使用AutoMapper可以在把所有規則都先寫在ProFile裡面,然後在Global一次註冊,之後在程式裡面用到就不用每次再寫CreateMap的部分
**Profile : **
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ControllerMappingProfile : Profile
{
public override string ProfileName
{
get
{
return "ControllerMappingProfile";
}
}

protected override void Configure()
{
Mapper.CreateMap<AccountViewModel, AccountDTO>()
.ForMember(d => d.Address, o => o.MapFrom(s => string.Concat(s.City, s.District)));

Mapper.CreateMap<Group, AccountDTO>()
.ForMember(d => d.Account, o => o.Ignore())
.ForMember(d => d.Password, o => o.Ignore())
.ForMember(d => d.Address, o => o.Ignore())
.ForMember(d => d.GroupName, o => o.MapFrom(s => s.Name));
}
}

**AutoMapperConfig : **

1
2
3
4
5
6
7
8
9
10
11
public class AutoMapperConfig
{
public static void Configure()
{
Mapper.Initialize(x =>
{
x.AddProfile<ControllerMappingProfile>();
});
}
}

最後在Global Application_Start註冊即可 ```csharp
protected void Application_Start()
{
AutoMapperConfig.Configure();
}