iT邦幫忙

2022 iThome 鐵人賽

DAY 24
1
自我挑戰組

[Dot Net Core](圖解系列與常用套件)系列 第 24

[Dot Net Core](圖解系列) 24.AutoMapper - Implement Mapping object

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20220924/20144614JDID1WFwx6.jpg

上一節是 AutoMapper 在注入 Controller 建構子所做的準備工作。這節要看如何運作轉換類別對應。

https://ithelp.ithome.com.tw/upload/images/20220924/20144614qixZNM2QYr.jpg

上節準備工作最末,其中一個設定是 prfile 的設定,會將剛剛 MapperConfigurationExpression 的 List _profiles欄位 轉換到 AutoMapper.MapperConfiguration 的 ProfileMap[] Profiles 類別陣列裡。
之後會將此 ProfileMap 逐一取出,做 ProfileMap.BuildTypeMap:

private void BuildTypeMap(IGlobalConfiguration configurationProvider, ITypeMapConfiguration config)
{
	var typeMap = new TypeMap(config.SourceType, config.DestinationType, this, config.IsReverseMap);
	config.Configure(typeMap);
	configurationProvider.RegisterTypeMap(typeMap);
}

而在 產生 TypeMap 實體時, 建構子會將目的類別的成員資訊取出,包含成員的 Type 屬性,與 命名 屬性。

public TypeMap(Type sourceType, Type destinationType, ProfileMap profile, bool isReverseMap = false)
{
	Types = new(sourceType, destinationType);
	Profile = profile;
	SourceTypeDetails = profile.CreateTypeDetails(sourceType);
	DestinationTypeDetails = profile.CreateTypeDetails(destinationType);
	var sourceMembers = new List<MemberInfo>();
	foreach (var destinationProperty in DestinationTypeDetails.WriteAccessors)
	{
		sourceMembers.Clear();
		var propertyType = destinationProperty.GetMemberType();
		if (profile.MapDestinationPropertyToSource(SourceTypeDetails, destinationType, propertyType, destinationProperty.Name, sourceMembers, isReverseMap))
		{
			AddPropertyMap(destinationProperty, propertyType, sourceMembers);
		}
	}
}

之後主要會有二個步驟:

Step1:

欄位命名做對應,取出對應來源類別的相同命名的屬性之 System.Reflection.MemberInfo,轉存到 PropertyMap,並加入到 TypeMap 的 Dictionary<string, PropertyMap> _propertyMaps裡。
如果有擴充功能之設定,會依照設定加入 TypeMap 之設定。 目的與來源類別的互相轉換組合會再以 TypeMap 的封裝加入到 AutoMapper.MapperConfiguration 的 Dictionary<TypePair, TypeMap> _configuredMaps裡。

Step2:

執行每份 _configuredMaps 中對應 typeMap.Seal -> TypeMap.CreateMapperLambda 。
基本上,要組出的轉換函式會先去 new 目的類別實體,然後對每個 來源類別成員的值 指派到 目的類別對應欄位,如果轉換型別過程找不到來源類別的成員,就使用目的成員的預設值。但這是最基本的 apply。
最後會將 Lambda Expression 指派到 typeMap.MapExpression中。

之後會將 _configuredMaps 經過設定檢查後指派到 _resolvedMaps 。

https://ithelp.ithome.com.tw/upload/images/20220924/20144614BIvn4Ca4bL.jpg

當執行:

_mapper.Map<Product, ProductDTO>(product)

會透過 MapCore 函式, 再呼叫 AutoMapper.MapperConfiguration 的 GetExecutionPlan , 進而呼叫之前準備工作時委派的 BuildExecutionPlan。 隨後執行 ResolveTypeMap 將欲做 Mapping 轉換的 TypeMap 取出,
然後傳入此 TypeMap 實體給 GenerateTypeMapExpression 函式。接著執行 TypeMap.MapExpression,將目的類別實體產出。

AutoMapper 有許多複雜且多情境的轉換,以上先以基本款轉換做運作說明。


上一篇
[Dot Net Core](圖解系列) 23. AutoMapper - Process of that Registering package into DI
下一篇
[Dot Net Core](圖解系列) 25. 優秀套件之運作 - Autofac 運作圖解
系列文
[Dot Net Core](圖解系列與常用套件)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言