🚫 Ad Blocker Detected

Please disable your AD blocker to continue using this site. Ads help us keep the content free! please press keyboard F5 to refresh page after disabled AD blocker

請關閉廣告攔截器以繼續使用本網站。廣告有助於我們保證內容免費。謝謝! 關閉後請按 F5 刷新頁面

0%

(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 欄位由 UserInfoModel  Name Age 屬性組成的

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 許可協議。轉載請註明出處!

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