iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
自我挑戰組

Bug仔的筆記本系列 第 10

使用反射來實作一個 AutoMapper

  • 分享至 

  • xImage
  •  

延續昨天的使用 AutoMapper 的主題。如果你的專案不能使用 AutoMapper 的話,那就只能使用反射(Reflection)來實作了。今天我們用反射(Reflection)來把 UserViewModel 的資料倒進 Model裡面。
https://ithelp.ithome.com.tw/upload/images/20220924/20120420cE4kaQVlhj.png

以下程式,我們先進行用反射的方式取得物件全部屬性(Property)的值。

var userViewModel = new UserViewModel(){
    Id=1,
    Email="aaa@test.com",
    Name="長庚",
    Phone="123456789"
};

// 先取出 UserViewModel 型別中所有 Property 資訊 (PropertyInfo型別)
var propertyInfos = typeof(UserViewModel).GetProperties();

// 迴圈對 UserViewModel 型別的各個 PropertyInfo 處裡
foreach (var propertyInfo in propertyInfos)
{
    // 把 userViewModel 餵給 propertyInfo,來取得 userViewModel 該 Property 的值
    var value = propertyInfo.GetValue(userViewModel);
    Console.WriteLine($"{propertyInfo.Name}:{value}");
}

輸入結果

Id:1
Email:aaa@test.com
Name:長庚
Phone:123456789

對物件賦值

再下一步就是把值餵給目標物件的同名屬性(Property)。我們稍微改一下程式。

上面不變先省略 ...

// 宣告要被賦值的目標物件
var user = new User();
// 迴圈對來源型別的各個 PropertyInfo 處裡
foreach (var propertyInfo in propertyInfos)
{
    // 把 userViewModel 餵給 propertyInfo,來取得 userViewModel 該 Property 的值
    var value = propertyInfo.GetValue(userViewModel);

    // 取得目標型別 (User) 的 propertyInfo 
    var userPropertyInfo = typeof(User).GetProperty(propertyInfo.Name);
    // 使用 User 的 propertyInfo 對目標物件 (user) 的該 Property 賦值
	userPropertyInfo.SetValue(user, value);
}

結果

https://ithelp.ithome.com.tw/upload/images/20220925/201204201waHKjNxbu.png

使用泛型,使之能通用

上面的寫法是固定型別的,我們用泛型來稍微改造一下,就可以一個方法能讓全部型別可以 Map 為其他型別(當然要欄位名稱同樣)。

 public static class MyMapper
    {
        public static TTarget Map<TOrigin, TTarget>(TOrigin origin) where TTarget : new()
        {
            if (origin == null)
            {
                throw new ArgumentNullException();
            }

            var target = new TTarget();

            // 先取出來源型別中所有 Property 資訊 (PropertyInfo型別)
            var propertyInfos = typeof(TOrigin).GetProperties();
            // 迴圈對型別的各個 PropertyInfo 各自處裡
            foreach (var propertyInfo in propertyInfos)
            {
                // 把物件餵給 property,來取得此物件此 Property 的值
                var value = propertyInfo.GetValue(origin);

                // 取得目標型別的 Property 
                var targetProperty = typeof(TTarget).GetProperty(propertyInfo.Name);
                // 使用目標型別的 propertyInfo 對目標物件的該 Property 賦值
                targetProperty?.SetValue(target, value);
            }

            return target;
        }
    }

這樣我們只要一行就能把 ViewModel 的資料,倒進 Model 裡!!!
https://ithelp.ithome.com.tw/upload/images/20220925/20120420yI0EdhBApV.png


上一篇
使用 AutoMapper 幫我們把 ViewModel 的資料倒進 Model 裡
下一篇
用前端 JavaScript 來做圖片壓縮
系列文
Bug仔的筆記本30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言