系列介紹
[非專業翻譯] 是對沒有中文文檔進行翻譯的系列博客,文章由機翻和譯者自己理解構成,和原文相比有所有不同,但意思基本一致。
因個人能力有限,如有謬誤之處還請指正,多多包涵。
正文
本文將說明 Mapster 中的 配置位置
入口
映射配置應該只初始化並且只進行一次配置。因此在編寫代碼的時候不能將映射配置和映射調用放在同一個地方。
例如下面的例子,運行將會拋出一個異常:
config.ForType<Poco, Dto>().Ignore("Id");
var dto1 = poco1.Adapt<Dto>(config);
config.ForType<Poco, Dto>().Ignore("Id"); //<--- 這里將拋出異常,因為在這之前已經觸發過了映射
var dto2 = poco2.Adapt<Dto>(config);
所以,在編寫代碼時應該將映射配置和映射調用分開,將映射配置放到程序的入口,例如:
Main
方法Global.asax.cs
Startup.cs
// Application_Start in Global.asax.cs
config.ForType<Poco, Dto>().Ignore("Id");
// in Controller class
var dto1 = poco1.Adapt<Dto>(config);
var dto2 = poco2.Adapt<Dto>(config);
保證配置實例和映射配置在同一位置
將配置實例和映射配置分開,可能會導致代碼處於不同的位置,在代碼編寫過程中可能會出現遺漏之類的問題。
使用 Fork
函數可以使配置實例與映射配置在同一位置:
var dto = poco.Adapt<Dto>(
config.Fork(forked => forked.ForType<Poco, Dto>().Ignore("Id"));
不用擔心性能問題,只有第一次使用配置實例時會編譯,之后的調用將從緩存中獲取。
在泛型類或方法中使用 Fork
Fork
方法默認使用文件名、行號作為鍵值。但是如果在在泛型類或泛型方法中調用Fork
方法,必須指定鍵和類型全名稱,防止 Fork
從不同的類型參數返回無效的配置。
IQueryable<TDto> GetItems<TPoco, TDto>()
{
var forked = config.Fork(
f => f.ForType<TPoco, TDto>().Ignore("Id"),
$"MyKey|{typeof(TPoco).FullName}|{typeof(TDto).FullName}");
return db.Set<TPoco>().ProjectToType<TDto>(forked);
}
不同的程序集
映射配置處於多個不同的程序集是比較常見的情況。
也許你的域程序集有一些映射到域對象的規則,而你的 web api 有一些特定的規則來映射到您的 api 約定。
Scan 方法
Mapster 支持掃描程序集注冊映射配置,可以幫助你快速注冊映射配置並減小忘記編碼注冊配置的機率。
在某些特定的情況下可以順序注冊程序集,以達到重寫映射配置的目的。
掃描程序集注冊映射配置非常簡單,只需要在程序集中創建一個或多個 IRegister
的實現,然后調用 TypeAdapterConfig
實例的 Scan
方法即可:
public class MyRegister : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.NewConfig<TSource, TDestination>();
//OR to create or enhance an existing configuration
config.ForType<TSource, TDestination>();
}
}
使用全局配置實例掃描程序集中的配置注冊器:
TypeAdapterConfig.GlobalSettings.Scan(assembly1, assembly2, assemblyN)
或使用特定的配置實例掃描程序集中的配置注冊器:
var config = new TypeAdapterConfig();
config.Scan(assembly1, assembly2, assemblyN);
Apply 方法
如果你使用的是其它 程序集掃描庫(如 MEF ), 那么你可以調用配置實例的 Apply
方法將映射配置注冊器添加到配置實例中:
var registers = container.GetExports<IRegister>();
config.Apply(registers);
Apply
方法允許你選擇某些 映射配置注冊器 添加到 配置實例 中,而不是像 Scan
方法把程序集里的所有 映射配置注冊器 添加到 配置實例 中:
var register = new MockingRegister();
config.Apply(register);
特性標簽
Mapster 支持通過為類型增加 特性標簽 的方式 添加類型映射配置:
[AdaptTo(typeof(StudentDto), PreserveReference = true)]
public class Student {
...
}