0%

AutoMapper Generic 對應

此篇文章用的AutoMapper版本 : 6.2.2 <套件連結>

被同事問到AutoMapper有沒有辦法做泛型的對應,問了一下才發現其他人原來也沒嘗試過這樣的作法,所以來筆記一下供之後參考。

首先對應的Class如下

1
2
3
4
5
6
7
8
9
10
11
12
public class Source<T>
{
public int Page1 {get;set;}
public T Value { get; set; }
}

public class Destination<T>
{
public int Page {get;set;}
public T Value { get; set; }
}

希望能將Source<T>對應到Destination<T>,而這邊的泛型T有兩組分別如下

1
2
3
4
5
6
7
8
9
10
public class Test
{
public string Name {get;set;}
}

public class Test1
{
public string NickName { get; set; }
}

同事原本寫的Mapper Configuration對應如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Source<Test>, Destination<Test1>>()
.ForMember(d => d.Page, o => o.MapFrom(s => s.Page1))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Value));

cfg.CreateMap<Test, Test1>()
.ForMember(d => d.NickName, o => o.MapFrom(s => s.name));
});

var mapper = config.CreateMapper();
Source<Test> Source = new Source<Test>
{
Page = 1,
Value = new Test
{
name = "hi"
}
};
Destination<Test1> Result = mapper.Map<Source<Test>, Destination<Test1>>(Source);

這樣寫對應會過,但是變成泛型的T有多種可能時,要寫多組的Source與Destination對應,喪失了AutoMapper的重用性

1
2
3
4
5
6
7
8
9
10
cfg.CreateMap<Source<NewClass2>, Destination<NewClass2>>()
.ForMember(d => d.Page, o => o.MapFrom(s => s.Page))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Value));

cfg.CreateMap<Source<NewClass3>, Destination<NewClass4>>()
.ForMember(d => d.Page, o => o.MapFrom(s => s.Page))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Value));

//............一直往下增加

能不能讓Source與Destination設定一次就好,之後只要多寫Generic的Type對應即可,其實AutoMapper是有提供的,方式如下

1
2
3
4
cfg.CreateMap(typeof(Source<>), typeof(Destination<>))
.ForMember("Page",o => o.MapFrom("Page1"))
.ForMember("Value",o => o.MapFrom("Value"));

之後只要針對泛型的Class補充即可,Source對應到Destination就已經設定完了,以上供參考