2012-06-28 31 views
3

我正在把一個.Net 4庫放在一起,它被設計成作爲一個獨立的程序集來分發。部分圖書館會進行一些特定的Web服務調用,我計劃將調用的版本返回給圖書館的使用者。 Web服務響應表示與圖書館消費者實際獲得的內容之間需要進行大量的映射。我希望利用AutoMapper來完成這項任務;多數情況下,約定將能夠爲我處理許多無聊的從右到左的映射代碼。在獨立,可重用的庫中,建議在AutoMapper中創建地圖的方法是什麼?

因此,例如,我的圖書館可能使代碼看起來有點像:

public Widget GetWidget(Guid id) 
{ 
    // Get server representation 
    ServerWidget serverWidget = this.Request<ServerWidget>(id); 

    // Map to client representation 
    Widget clientWidget = Mapper.Map<ServerWidget, Widget>(serverWidget); 

    return clientWidget; 
} 

其他地方的代碼我已經顯然需要調用(加上映射任何自定義配置):

Mapper.CreateMap<ServerWidget, Widget>(); 

Per design guidelines of AutoMapper,這應該只對每個AppDomain執行一次(因爲它是一個昂貴的操作)。由於這個庫可以用於任何數量的可能環境(ASP.NET,WinForms應用程序,WPF應用程序,單元測試運行器等),因此如何在這種情況下正確設置地圖?很顯然,我的代碼可能會暴露某種方法讓客戶端調用「初始化事物」(在這種情況下爲映射器),並假定他們確實進行了這種調用,並且在應用程序啓動過程中的正確時間,但這對於強加給圖書館的消費者似乎是一個非常蹩腳的要求。

任何人對我有任何建議和/或可以指向GitHub,Codeplex等已經在做這樣的事情的開源項目?

回答

2

如何在你的庫中的靜態IsMappingInitialised方法,你做這樣的映射前檢查,這是線程安全的:

private static readonly object MappingLock = new object(); 
private static bool _ready = false; 

public static bool IsMappingInitialised() 
{ 
    if (!_ready) 
    { 
     lock (MappingLock) 
     { 
      if (!_ready) 
      { 
       Mapper.CreateMap<ServerWidget, Widget>(); 
       _ready = true; 
      } 
     } 
    } 

    return _ready; 
} 

這樣你不必依靠你的消費者開展初始化。

+0

謝謝,這對我的需求很好。 – ckittel

2

您還可以使用.Net的static constructor功能。 在你的類中添加一個靜態構造函數並添加地圖的創建。您不需要任何鎖定,因爲CLR確保每個AppDomain只能執行一次靜態構造函數。由於您使用的是靜態映射器(AutoMapper.Mapper),這對於您的情況也是足夠的,這也是每個AppDomain的一個映射器。

相關問題