(AutoMapper)反射自動註冊AutoMapper Profile

前言:

AutoMapper 幫我我們方便管理物件跟物件之間屬性值格式轉換

模型轉換

這裡有兩個類別

UserInfoModel 當作我們從DB撈取出來 模型資料

1
2
3
4
5
6
public class UserInfoModel
{
public int RowId { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

UserInfoViewModel 是呈現在UI或其他地方的模型

其中 Detail欄位由 UserInfoModelNameAge屬性組成的

1
2
3
4
public class UserInfoViewModel
{
public string Detail { get; set; }
}

這時我們就會引用 AutoMapper 幫我們統一管理轉換模型上的問題

建立一個Profile

設置UserInfoModel對於 UserInfoViewModel之前的欄位轉換

1
2
3
4
5
6
7
8
9
public class UserInfoProfile : Profile
{
        public UserInfoProfile()
        {
            CreateMap<UserInfoModel, UserInfoViewModel>()
                    .ForMember(t => t.Detail, 
                                    s => s.MapFrom(_ => $"DetailInfo:{_.Name} {_.Age}"));
        }
}

而我們在註冊時會呼叫 AddProfile方法

1
Mapper.Initialize(x => x.AddProfile<UserInfoProfile>());

但每次新加Profile這邊都需要設置新的Profile,我們就會想有沒有方法可以讓他自動註冊?

我們可以使用反射來完成

反射自動註冊AutoMapper Profile

此程式我使用我的 ExtenionTool

1
2
3
4
5
6
7
var profiles =  Assembly.GetExecutingAssembly()
.GetInstancesByAssembly<Profile>();

foreach (var profile in profiles)
{
Mapper.Initialize(x => x.AddProfile(profile));
}

上面程式碼很簡單清晰,呼叫 取得目前組件所有的 Profile物件實體並且加到Profile中,我們將上面程式碼在初始化執行一次

1
2
3
4
5
6
7
public static IEnumerable<TResult> GetInstancesByAssembly<TResult>(this Assembly ass)
{
return ass.GetTypes()
.Where(x => typeof(TResult).IsAssignableFrom(x) && x.IsNormalClass())
.Select(x => Activator.CreateInstance(x))
.Cast<TResult>();
}

核心程式使用Linq 動態取得你所需的類型並使用反射創建

之後我們就可以不用在手動把Profile加至AutoMapper容器中了

Source Code

此文作者:Daniel Shih(石頭)
此文地址https://isdaniel.github.io/automapperinit/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!


如果本文對您幫助很大,可街口支付斗內鼓勵石頭^^