AutoMapper总结
生活随笔
收集整理的這篇文章主要介紹了
AutoMapper总结
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
AutoMapper是一個(gè)對(duì)象和對(duì)象間的映射器。對(duì)象與對(duì)象的映射是通過(guò)轉(zhuǎn)變一種類(lèi)型的輸入對(duì)象為一種不同類(lèi)型的輸出對(duì)象工作的。讓AutoMapper有意思的地方在于它提供了一些將類(lèi)型A映射到類(lèi)型B這種無(wú)聊的事情的有趣慣例。只要類(lèi)型B遵守AutoMapper已經(jīng)建立的慣例,大多數(shù)情況下,映射兩種類(lèi)型零配置就可以了。
首先,需要有source(源)和destination(目標(biāo))類(lèi)型。默認(rèn)情況下AutoMapper 只要Destination類(lèi)型的成員名字與Source類(lèi)型的成員名字匹配(成員名稱(chēng)不區(qū)分大小寫(xiě)),并且成員類(lèi)型相同就直接會(huì)將值傳遞給Destination類(lèi)型。 AutoMapper只要做一次初始化就可以使用,因此最好的配置代碼的地方應(yīng)該在應(yīng)用啟動(dòng)時(shí)。初始化處理(Profile實(shí)例)
Initialize():實(shí)例化Mapper對(duì)象 CreateMap():創(chuàng)建映射關(guān)系 Ex:Mapper.Initialize(cfg=>{ cfg.CreateMap<Source, Dest>(); }); AddProfile:使用配置文件創(chuàng)建映射關(guān)系 Ex: Mapper.Initialize(cfg=>{cfg.AddProfile<MyProfile>(); });對(duì)于MyProfile對(duì)象需要繼承Profile對(duì)象,并重寫(xiě) Configure()方法。映射前后操作:
BeforeMap(): 在映射前執(zhí)行的處理。Ex:BeforeMap((src, dest) => src.Value = src.Value + 1) AfterMap(): 在映射后執(zhí)行的處理。 Ex:AfterMap((src, dest) => src.Name = "FengTest")條件映射
ForMember():對(duì)于映射中成員的處理。 Condition():對(duì)于條件映射處理,滿(mǎn)足該條件才會(huì)給目標(biāo)成員賦值。 Ex:ForMember(dest => dest.Value, opt => opt.Condition(src => src.Value > 0 && src.Value < 130));命名慣例
SourceMemberNamingConvention :源類(lèi)型成員命名規(guī)則 Ex: cfg.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention(); //下劃線(xiàn)命名法 cfg.DestinationMemberNamingConvention :目標(biāo)類(lèi)型成員命名規(guī)則 Ex: cfg.DestinationMemberNamingConvention = new PascalCaseNamingConvention(); //帕斯卡命名法替換字符
ReplaceMemberName():將源成員名稱(chēng)中的字符替換成新的字符此方法必須在CreateMap之前 Ex: cfg.ReplaceMemberName("Tool", "Car");前后綴
RecognizePrefixes():識(shí)別源成員名稱(chēng)中的前綴字符 Ex: cfg.RecognizePrefixes("P"); RecognizePostfixes():識(shí)別源成員名稱(chēng)中的后綴字符 Ex: cfg.RecognizePostfixes("L"); 此方法必須在CreateMap之前,并且默認(rèn)是識(shí)別“Get”字符前綴 ClearPrefixes(): 清除前綴 Ex:cfg.CliearPrefixes()全局過(guò)慮?
ShouldMapField : 字段的映射條件 Ex: cfg.ShouldMapField = field => false; //不映射任何字段 ShouldMapProperty:屬性的映射條件 Ex:cfg.ShouldMapProperty = pro => pro.GetMethod != null && pro.GetMethod.IsPrivate; 此方法必須是源類(lèi)型與目標(biāo)類(lèi)型都滿(mǎn)足該條件才能映射處理,默認(rèn)情況下AutoMapper只對(duì)公共成員做映射,如果想識(shí)別Private/internal,可以修改這兩個(gè)屬性值。構(gòu)造函數(shù)?
默認(rèn)情況下,當(dāng)目標(biāo)類(lèi)型的構(gòu)造函數(shù)中的參數(shù)名稱(chēng)、類(lèi)型與源類(lèi)型成員的名稱(chēng)、類(lèi)型相同,AutoMapper會(huì)自動(dòng)映射。 當(dāng)構(gòu)造函數(shù)的參數(shù)名稱(chēng)與目標(biāo)成員的名稱(chēng)不同時(shí),可使用ForCtorParam()方法指定。 ForCtorParam() : 對(duì)構(gòu)造函數(shù)參數(shù)映射Ex:ForCtorParam("age1",user=>user.MapFrom(src=>src.Age))條件對(duì)象映射器
AddConditionalObjectMapper():符合條件后兩個(gè)類(lèi)型自動(dòng)映射。 Ex:cfg.AddConditionalObjectMapper().Where((s, d) => d.Name == s.Name + "Dto");成員配置
AddMemberConfiguration():配置文件, 配置中的東西都是以該方法開(kāi)始的。 Ex:cfg.AddMemberConfiguration().AddMember<NameSplitMember>(); 默認(rèn)配置 AddName<ReplaceName>(r => r.AddReplace("B", "A")) 替換字符 AddName<PrePostfixName>(p => p.AddStrings(pr => pr.Prefixes, "Get", "get"))識(shí)別前綴 AddName<PrePostfixName>(p => p.AddStrings(pr => pr.Postfixes, "Set", "set"))識(shí)別后綴 AddName<SourceToDestinationNameMapperAttributesMember>() 特性支持 [MapToAttribute("Phone")] :特性,匹配基于給定名稱(chēng)的屬性 AutoMapper默認(rèn)值:AddMemberConfiguration().AddMember<NameSplitMember>() .AddName<PrePostfixName>(_ => _.AddStrings(p => p.Prefixes,"Get")) .AddName<SourceToDestinationNameMapperAttributesMember>(); AddName和AddMember中的每個(gè)類(lèi)型都是基于ISourceToDestinationNameMapper和IChildMemberConfiguration接口的。也可以創(chuàng)建自己的類(lèi)通過(guò)Lambda語(yǔ)句參數(shù)來(lái)配置屬性,因此你可以微調(diào)AutoMapper如何解析屬性映射。自定義類(lèi)型轉(zhuǎn)換
在作對(duì)象之間的轉(zhuǎn)換時(shí),有些屬性的類(lèi)型是不能直接轉(zhuǎn)換的,但經(jīng)過(guò)驗(yàn)證,默認(rèn)可以將string類(lèi)型映射為int和DateTime類(lèi)型。方法一:
ConvertUsing() :使用映射的方式 Ex: cfg.CreateMap<Source, Destination>().ConvertUsing(s => { var d = new Destination(); d.Value1 = System.Convert.ToInt32(s.Value1); d.Value2 = System.Convert.ToDateTime(s.Value2); d.Value3 = Type.GetType(s.Value3); return d; });方法二:
定一個(gè)類(lèi),該類(lèi)型需要繼承 ITypeConverter泛型接口,源類(lèi)型和目標(biāo)類(lèi)型,并且實(shí)現(xiàn)Convert方法 Ex: public class CustomTypeConverter : ITypeConverter<Source, Destination> 然后在Mapper.Initialize的時(shí)候使用ConvertUsing的泛型方法 Ex: cfg.CreateMap<Source, Destination>().ConvertUsing<CustomTypeConverter>();方法三:
定一個(gè)類(lèi),該類(lèi)型需要繼承ITypeConverter泛型接口,源基礎(chǔ)類(lèi)型和目標(biāo)基礎(chǔ)類(lèi)型,并且實(shí)現(xiàn)Convert方法 Ex:public class TypeConverter : ITypeConverter<string, Type> 然后在Mapper.Initialize的時(shí)候創(chuàng)建該基類(lèi)型的映射,該方式在Mapper全局都是有效的 Ex: Mapper.Initialize(cfg => { cfg.CreateMap<string, Type>().ConvertUsing<TypeConverter>(); cfg.CreateMap<Source, Destination>(); });自定義值解析
雖然AutoMapper覆蓋了很大一部分目標(biāo)成員的映射場(chǎng)景,但還是有一部分需要自定義處理。因是對(duì)目標(biāo)類(lèi)的中的某一個(gè)屬性的賦值處理,因些會(huì)用到ForMember()方法。使用ResolveUsing() :指定賦值的方式。方法一:
Ex:cfg.CreateMap<Source, Destination>().ForMember(dest => dest.Total, opt => { opt.ResolveUsing(s => { var destination = new Destination(); destination.Total = s.Value1 + s.Value2; return destination.Total; }); });方法二:
創(chuàng)建一個(gè)類(lèi),并實(shí)現(xiàn)IValueResolver方法 Ex: public class MyValueResolver : IValueResolver<Source, Destination, int> 然后在創(chuàng)建映射關(guān)系的時(shí)候?yàn)槠涓馁x值方式 Ex: cfg.CreateMap<Source, Destination>().ForMember(dest => dest.Total, opt => { opt.ResolveUsing<MyValueResolver>(); });Dynamic和ExpandoObject映射
Dynamic動(dòng)態(tài)創(chuàng)建對(duì)象 Ex:dynamic dynamicObj = new ExpandoObject();//ExpandoObject對(duì)象包含可在運(yùn)行時(shí)動(dòng)態(tài)添加或移除的成員. 雖然Dynamic為動(dòng)態(tài)對(duì)象不有辦法創(chuàng)建映射關(guān)系,但必須先對(duì)Mapper實(shí)例化,才能使用。 Ex: public static ExpandoObject DynamicAndExpandoObject() { Mapper.Initialize(cfg=> { }); dynamic dynamicObj = new ExpandoObject(); dynamicObj.Age = 12; dynamicObj.Name = "Feng測(cè)試"; Person person = Mapper.Map<Person>(dynamicObj); Console.WriteLine("person.Age={0},Name={1}", person.Age, person.Name); dynamic dynamicSecond = Mapper.Map<ExpandoObject>(person); dynamicSecond.Address = "北京"; Console.WriteLine("dynamicObj.Age={0},Name={1},Address={2}", dynamicSecond.Age, dynamicSecond.Name, dynamicSecond.Address); return dynamicSecond; }List和數(shù)組
AutoMapper只要求元素類(lèi)型的配置而不要求可能會(huì)用到的任何數(shù)組或者list類(lèi)型。因此的創(chuàng)建映射的配置中,只是配置類(lèi)型之間的映射,而不需要設(shè)計(jì)任何集合類(lèi)型。 具體來(lái)說(shuō),支持的源集合類(lèi)型包括:-
- IEnumerable
- IEnumerable<T>
- ICollection
- ICollection<T>
- IList
- IList<T>
- List<T>
- Arrays
集合中的多態(tài)元素類(lèi)型
AutoMapper支持多態(tài)數(shù)組和集合,因此如果發(fā)現(xiàn)派生的源或者目標(biāo)類(lèi)型就會(huì)自動(dòng)轉(zhuǎn)換,但創(chuàng)建的時(shí)候需要聲明。 Ex:cfg.CreateMap<ParentSource, ParentDestination>().Include<ChildSource, ChildDestination>(); 但也需要聲明子類(lèi)型的映射,因?yàn)锳utoMapper“猜不出”具體是哪個(gè)子類(lèi)型 Ex:cfg.CreateMap<ChildSource, ChildDestination>(); 也可以聲明子類(lèi)型的映射,再包含基類(lèi)型,但也要再聲明基類(lèi)型的映射 Ex:cfg.CreateMap<ParentSource, ParentDestination>(); cfg.CreateMap<ChildSource, ChildDestination>().IncludeBase<ParentSource, ParentDestination>();?
Null值替換
當(dāng)源類(lèi)型中某個(gè)屬性為空值的時(shí)候在映射到目標(biāo)類(lèi)型時(shí),目標(biāo)類(lèi)型的該屬性可以設(shè)置一個(gè)默認(rèn)值 NullSubstitute(),如果源屬性為空,則用該方法設(shè)置默認(rèn)值。 Ex: cfg.CreateMap<Person, PersonInfo>().ForMember(dest => dest.Title, opt => opt.NullSubstitute("屌絲")); 學(xué)習(xí)來(lái)源:http://www.cnblogs.com/farb/p/4932692.html 本文來(lái)自:https://www.cnblogs.com/xiao-feng/p/6411226.html 代碼地址:https://github.com/HaiFengNet/AutoMapperDemo轉(zhuǎn)載于:https://www.cnblogs.com/shiyilang398/p/11360518.html
總結(jié)
以上是生活随笔為你收集整理的AutoMapper总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: S5700交换机MAC地址绑定问题
- 下一篇: 神策数据新 DEMO 上线,助力零售行业