首頁  >  文章  >  後端開發  >  使用AutoMapper實作Dto和Model的自由轉換(上)

使用AutoMapper實作Dto和Model的自由轉換(上)

巴扎黑
巴扎黑原創
2016-12-20 11:28:461581瀏覽

在實際的軟體開發專案中,我們的「業務邏輯」常常需要我們對同樣的資料進行各種變換。例如,一個Web應用程式透過前端收集使用者的輸入成為Dto,然後將Dto轉換成領域模型並持久化到資料庫中。另一方面,當使用者要求資料時,我們又需要做相反的工作:將從資料庫中查詢出來的領域模型以相反的方式轉換成Dto再呈現給使用者。有時候我們也會面臨更多的資料使用需求,例如有多個資料使用的客戶端,每個客戶端都有自己對資料結構的不同需求,而這也需要我們進行更多的資料轉換。
頻繁的資料轉換瑣碎而又凌亂,很多時候我們不得不: 
(1)在兩個類型幾乎只是名字不同而結構大體相似,卻只能以手工的、逐個屬性賦值的方式實現數據在類型間的“傳遞”。 
(2)每遇到一個新的資料轉換場景就手動實現一套轉換邏輯,導致資料轉換操作重複而又分散到應用的各個角落。
如果有這樣一個“變形金剛”般的工具,把“橘子”變成我們想要的“蘋果”,而我們需要做的只是定義好轉換規則——做我們真正的業務邏輯,或者甚至在簡單場景下連規則都不需要定義(Convention Over Configuration),那將會是一件非常美好的事情。事實上在.NET中我們不用重複發明輪子,因為我們有-AutoMapper,一個強大的Object-Object Mapping工具。 
好吧,我承認自己有一點小小的激動,事實上我所做的項目正在經歷以上的“困惑”,而AutoMapper確實帶給我眼前一亮的感覺。因此我花了一點週末休息時間小小嘗試了一把AutoMapper,透過做小的應用場景實現Dto到領域模型的映射,確實感覺到了它的「強大氣場」。我將在文章中分享自己的使用心得,希望能為同樣處於困惑中的你帶來一點幫助。完整的專案程式碼我會在晚一些時候發佈到自己的git repository中,歡迎大家自由參考使用。 
【一】 應用場景說明 
先來看看我所」虛擬「的領域模型。這次我定義了一個書店(BookStore): 

C#代碼  

public class BookStore  

{  

   public List Books { get; set; }  

    public Address Address { get; set; }  

}  

書店有自己的地址(Address):

{  

    public string Country { get; set; }  

    public string City { get; set; }  

    public string Street { get }  

}  

同時書店裡放了n本書(Book):

C#代碼  

public class Book  

{  

    public string Ti { get; set; }  

    public string Language { get; set; }  

  Price { get; set; }  

    public List Authors { get; set; }  

    public Publisher Publisher { get; set; }  

    public int? Paperback { get; set; }  

}  

每本書都有出版商資訊(Publisher): 

C#  

  public string Name { get; set; }  

}  

每本書可以有最多2個作者的資料(Author): 

C#代碼  


public class Author  
; }  

    public string Description { get; set; }  

    public ContactInfo Cont ): 

C#代碼  


public class ContactInfo

{  

    public string Email { get; set; }  

    Twitter { get; set; }  

}  

差不多就是這樣了,一個有著層級結構的領域模型。 

再來看看我們的Dto結構。

在Dto中我們有與BookStore對應的BookStoreDto: 

C#代碼  


public class BookStoreDto  


    public List Books { get; set; }

    public AddressDto Address { get; set; }  

}  

  

{  

    public string Country { get; set; }  

    public string City { get; set; }  

    public string Street { get }  


}  

以及與Book相對應的BookDto: 

C#代碼  

public class BookDto  

{  

    public string Title { get) set; }  

    public string Language { get; set; }  

    public decimal Price { get; set; }  

    public DateTime? PublishDate { get; set; }  


    int? Paperback { get; set; }  

    public string FirstAuthorName { get; set; }  

    public string FirstAuthorDescription { get; set; }  

    public string FirstAuthorEmail AuthorBlog { get; set; }  

    public string FirstAuthorTwitter { get; set; }  ; set; }  

    public string SecondAuthorDescription { get; set; }  

     public string SecondAuthorBlog { get; set; }  

    public string SecondAuthorTwitter { get }  

注意到我們的BookDto」拉平了「整個Book的層級結構,一個BookDto裡攜帶了Book及其所有Author、Publisher等所有模式的資料。 

剛好我們來看Dto到Model的映射規則。

(1)BookStoreDto -> BookStore 

BookStoreDto中的欄位   BookStore的欄位   

Name   Name   

(2)AddressDto -> Address 

AddressDto中的欄位   Address中的場域   

Country    Country    

City    City    

Street    Street    

Street    Street  

PostCode    PostCode    


(3)BookDto -> Book。 
BookDto中的一些基本欄位可以直接對應到Book中的欄位。

BookDto中的字段   Book中的字段   

Title    Title    

Description    Description    

Description    Description    

Description    Description    

Description     Price    

PublishDate    PublishDate    

Paperback    Paperback    
Book
Paperback    Paperback    

Book分別使用」First「前綴和」Second「前綴的欄位來表示。因此,所有FirstXXX欄位都會對應成Book的Authors中的第1個Author對象,而所有SecondXXX欄位則會對應成Authors中的第2個Author物件。

BookDto中的欄位   Book中的Authors中的第1個Author物件中的欄位   

FirstAuthorName    Name    

🜒   ContactInfo.Email    

FirstAuthorBlog    ContactInfo.Blog    

FirstAuthorTwitter    注意上表中的ContactInfo.Email表示對應到Author物件的ContactInfo的Email字段,依序類推。類似的我們有: 

BookDto中的欄位   Book中的Authors中的第2個Author物件中的欄位   

SecondAuthorName    Name uthorEmail    ContactInfo.Email    

SecondAuthorBlog    ContactInfo.Blog    

SecondAuthorTwitter    ContactInfo .Twitter    

最後還有Publisher字段,它將對應到一個獨立的Publisher物件。 

BookDto中的欄位    Publisher中的欄位    

Publisher    Name    


之間的大坨就是如此簡單的需求

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:類型.GetType()下一篇:類型.GetType()