2012-05-18 50 views
29

現在我仰視AutoMapper代碼(評估它的我的工作項目之一),而且,坦率地說,我很驚訝:AutoMapper中的Mapper.Map是否線程安全?

  • 庫API是基於一個靜態接入點(Mapper類型),所以通常它的任何方法都必須是線程安全的
  • 但我沒有在代碼中找到任何這方面的證據。

所有我能找到是this issue,但即使在發言中似乎有不正確的:如果Map不使用線程安全的數據結構的內部,它不能也視爲線程安全的,如果我打算在非併發上下文中調用CreateMap,但要同時撥打Map

I.e.在例如AutoMapper中唯一可能的使用模式ASP.NET MVC應用程序是:

lock (mapperLock) { 
    ... Mapper.AnyMethod(...) ... 
} 

顯然,如果我是正確的,這是一個巨大的缺乏。

所以我有兩個問題:

  • ,對嗎?
  • 如果是的話,AutoMapper的最佳替代方案是什麼?
+0

主要關鍵似乎是通過'ThreadSafeList _typeMaps'進行的雙重檢查;是什麼讓你覺得它不是線程安全的?你認爲什麼***特別是不是線程安全的? –

+0

TypeMap是一個不可變的對象嗎? –

+0

你告訴我! (並且問題也是:即使不是,在任何時候都不恰當地更新,除了你)。你聲稱它不是線程安全的;請詳細說明你認爲不安全的事情。請注意,通常策略(一旦構建)未更新,因此唯一需要保護的是訪問戰略緩存,這似乎是正確完成的。 –

回答

32

鏈接的issue或多或少地回答你的問題:

Mapper.CreateMap不是線程安全的,也永遠是。但是, Mapper.Map是線程安全的。 Mapper靜態類只是MappingEngine和Configuration對象之上的一個精簡包裝器。

所以只能使用Mapper.CreateMap如果你在一個線程安全的方式做你的配置一箇中心位置

您的評論是:

我問這個,因爲我想就地使用前右側配置automatter, 即。我計劃將其配置爲非併發的 上下文,即〜lock(mapperConfigLock){Mapper.CreateMap()....; }, ,我擔心現在還不夠。

如果您正在進行就地配置,請不要使用靜態Mapper類。由於在GitHub的問題上意見建議使用直接映射引擎:

var config = 
    new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers()); 
config.CreateMap<Source, Destination>(); 
var engine = new MappingEngine(config); 

var source = new Source(); 
var dest = engine.Map(source); 

它的更多的代碼一點點,但你可以圍繞它創建自己的助手。 但是,在一個給定的方法中,所有東西都是本地的,所以沒有共享狀態不需要擔心線程安全。

+0

清除,非常感謝! –

+0

'以線程安全的方式處理一箇中心位置' - 我認爲無論如何都需要在問題中進行解釋,因爲可能會出現很多錯誤。 –

+0

@nemesv - 非常感謝,您的解決方案真的很有幫助! – Ronnix

0

這個問題可能有些過時,只是想在一點點調查後記錄一些我的發現。

Mapper是一個包裝類,用於包裝以創建新配置,以及靜態內存中的mapper新實例,所以嚴格來說它不是線程安全的,但只要您只初始化配置一次,就可以使用它。

MapperConfiguration創建映射器的新實例,並將配置記錄到其自己的實例內存空間中。

TLDR;

如果需要一次性初始化配置,選擇靜態API

如果需要初始化配置了很多次,擔心線程安全,選擇例如API