在進行一些MIS相關的項目開發中,我們經常會涉及到一些數據對象和視圖模型之間的互相轉換,
public class Customer //mapped from db
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int NumberOfOrders { get; set; }
public int IsVIP { get; set; }
}
public class CustomerViewItem
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int NumberOfOrders { get; set; }
public bool IsVIP { get; set; }
}
這樣兩個對象的屬性非常相似,並且往往屬性還不少,在這兩種對象之間互相轉換是一個非常枯燥的事情。純手工操作絕對是件吃力不討好的事情,此前我曾經寫過一個通過反射來比較這兩個對象,根據名稱和類型匹配屬性來互相賦值。拋開性能問題且不談,這樣做也有一個局限性,那就是有差異的屬性如何處理的問題,例如這里的 IsVIP屬性。
雖然這些問題也可以通過來擴充那個方法為轉換類來解決,但這種Object-Object Map操作已經有人總結出了一系列的比較完善的框架了,基於不重復造輪子的原則,這里我便推薦幾個佼佼者:
AutoMapper是我用得較多的一個庫,主要原因是它的接口非常簡潔,並且功能非常完善,基本上需要的功能都能通過很少的代碼實現。不過貌似它主要是通過反射來實現的,並沒有做多少性能優化,因此對於性能額手動映射比起來有較大差距。可以用於一些對性能要求不高的場合。
從其名字就可以看出,它是采用emit方式在運行時動態生成IL,性能基本上是接近手動編寫代碼的硬編碼的了。
ValueInjectter的設計理念貌似和AutoMapper不大一樣。它並不是像AutoMapper那樣專注着於兩個相似的對象之間的互相轉換,而是提供了非常靈活的兩個對象基於契約的轉換機制(屬性匹配也是契約的一種)。在兩個對象互轉方面它不像AutoMapper那樣面面俱到,但卻小巧而靈活。例如,它可以支持多個對象轉換為一個對象(AutoMapper也能實現,相對較為麻煩),能將一個url的參數轉換為對象。園子里有一篇文章可以看下:http://www.cnblogs.com/suijing/p/ValueInjecter_demo.html