Asp.net 面向接口可擴展框架的“類型轉化基礎服務”是我認為除了“核心容器”之外最為重要的組成部分
但是前面博文一出,爭議很多,為此我再寫一篇類型轉化基礎服務和各種Mapper結合的例子,順便對各種Mapper做個簡單的優缺點對比
我對第三方組件評介有三個標准,一、可用性,二、性能,三、易用性
本例子中四種Mapper以前我都沒使用過(因為以前我都用自己的Mapper),本次測試可能不准確,錯誤的地方請大家指正
AutoMapper使用的是4.2.1.0,需要.net4.5支持(我使用Nuget沒找到到.net4.0下可用的版本)
EmitMapper使用的是1.0版本,使用.net4.0
NLite使用的是0.9.6,使用.net4.0
TinyMapper使用的是2.0.0.40,使用.net4.0
一、簡單封裝
1、各種Mappers封裝項目截圖

2、各種Mapper封裝類




3、簡單個人第一印象
3.1 AutoMapper的dll有267k,比較大,感覺功能很全面
支持自定義配置,支持靜態方法和實例方法,提供默認實例, 支持傳Type來轉化,擴展性不錯,功能強大
3.2 EmitMapper的dll才99k,感覺功能比較簡練
提供默認實例,支持自定義配置
3.3 NLite的dll有646k,dll偏大,其中很多Mapper以外的功能,是個套件,如果需要其中的多項功能才比較划算(這里不展開)
3.4 TinyMapper的dll才47k,最輕量,如果功能和性能都不打折扣就完美了
只支持靜態方法
二、繼承類型轉化科目測試
1、繼承類型轉化可用性測試代碼




大家要看清楚,不管哪種Mapper,我都是用相同方法(GlobalServices.Instance.Convert<A, B>(a))來調用的
其一、這是為了各種Mapper測試的公平性,不要說那個多個if那個多個哈希
其二、也就是說,各種Mapper都可以使用“插件式”在本框架中運行,如果為了突然發現某種Mapper工具有“bug”,可以“秒切”為另一種Mapper,所有調用的地方幾乎都不用修改
2、測試結果

沒問題,以上四種Mapper輕松勝任,但是有一個細微的差別,AutoMapper是直接使用類型轉化處理繼承類型的轉化的,對象引用都是同一個。其他mapper應該是“copy”的
3、性能測試(100萬次)

A:TinyMapper最快
B:AutoMapper其次(沒想明白,直接類型轉化應該算“作弊”,卻還沒有TinyMapper快)
C:EmitMapper和NLiteMapper旗鼓相當,EmitMappe稍快
4、易用性不用說,都很簡單
三、簡單對象轉化科目測試
1、測試代碼



AutoMapper居然轉化失敗,實在令人失望,網上一查資料,需要擴展
2、對AutoMapper單獨擴展再測


擴展后可以正常轉化,而且擴展也非常簡單,但是這么簡單的代碼為什么非要使用者寫呢?我暫時還不太理解,至少易用性上是要扣分的
3、性能測試(10萬次)

A:TinyMapper再拔頭籌(除HandCode外),可喜可賀
B:EmitMapper其次,性能不錯,Emit果然效果好
C:再次是AutoMapper,是EmitMapper的1.5倍左右,AutoMapper沒有我想象的那么差
D:NLiteMapper墊底,不太明白,好像網上有說NLiteMapper也是使用Emit做的,或許我用的這個版本還不是Emit(為了盡可能的通用,我盡量使用.net4.0)
4、可用性總結,AutoMapper扣分,簡單映射還是要手動注冊規則
網上有人把每次使用AutoMapper時都嘗試注冊,雖然丑了點是個辦法,不知道是否對性能有影響
四、成員名映射科目測試
1、測試代碼

AutoMapper的配置規則

EmitMapper的配置規則

TinyMapper的配置規則


其實需求很簡單,把A轉化C,但是要把A的id屬性映射到C的AId屬性上,但是NLiteMapper我沒找到配置方法
2、測試結果

NLiteMapper我沒找到配置方法,所以AId屬性沒轉化成功,初步判斷NLiteMapper無法支持這種需求
3、性能測試(10萬次)

A:TinyMapper繼續頭籌,而且遙遙領先
B:EmitMapper其次,比TinyMapper差太遠了,對這種配置規則支持不好
C:再次是AutoMapper,比TinyMapper就差更遠了,還是對這種配置規則支持不好
D:NLiteMapper性能又墊底,而且還沒實現需求
4、易用性
A:TinyMapper擴展的方式最為“優美”,使用表達式增加新的映射規則,得分最高
B:AutoMapper擴展的方式其次,因為每對類型都配置是硬傷
C:EmitMapper擴展的方式有點糟糕了,就是硬編碼,但是性能卻比硬編碼差多了,比TinyMapper都差不少(原因以后可以探討一下)
D:NLiteMapper墊底,沒實現需求
五、樹狀遞歸轉化科目測試
1、測試代碼


以上代碼是故意把TinyMapper注釋了,是為了單獨測試(TinyMapper會出嚴重錯誤)
2、測試結果

2.1、單獨測試TinyMapper

A:這次TinyMapper不行了,估計是我測試的例子特殊,子對象的類型是本身觸發了Bug,嚴重的bug,不只是不能轉化成功,直接死循環
注:不知道TinyMapper最新版本是否有這個問題,感興趣的可以測試一下
B:其他三種Mapper都能勝任
3、性能測試(10萬次,除TinyMapper外)

A:這次EmitMapper拔得頭籌
B:AutoMapper和NLiteMapper差不多,AutoMapper稍好一點
C:TinyMapper缺席,執行會報錯
4、易用性
AutoMapper硬傷,每對類型都要配置
總結一下,其一、網上有很多開源項目組件已經很強大了,如果能很好的未我所用可以大大加快項目開發的速度,甚至是項目的優化(含性能);其二、網上的項目也是人開發的,總會有這樣或者那樣的“問題”。我們要以一個包容的心態對待這些項目。一般來說功能全面,使用方便,bug少的性能可能不好;我們需要用其長,避其短。最好遵循“里氏代換原則”和“最少知識原則”,如果這個組件已經不適用了可以方便的替換不用滿項目的修改。
