2012-05-18 11 views
29

Czekam aż kod AutoMapper teraz (oceniając go za jednego z projektów pracuję nad) i, szczerze mówiąc, jestem bardzo zaskoczony:Czy Mapper.Map w AutoMapper wątku bezpieczne?

  • API biblioteki jest oparta na jednym statycznym punkt dostępu (typ Mapper), więc ogólnie każda z jego metod musi być bezpieczna dla wątków
  • Ale nie znalazłem ŻADNEGO dowodu tego w kodzie.

Wszystko udało mi się znaleźć to this issue, ale nawet wypowiedź wydaje się nieprawidłowy: jeśli Map nie używa struktury danych wątku bezpieczny wewnętrznie, to nie można uznać za bezpieczny wątku, jak również, jeśli mam zadzwonić pod numer CreateMap w kontekście innym niż współbieżny, ale jednocześnie z Map.

tj. jedyny możliwy wzór użycia AutoMappera w Aplikacja ASP.NET MVC to:

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

Oczywiście, jeśli mam rację, to jest duży brak.

Mam więc dwa pytania:

  • mam rację?
  • Jeśli tak, jaka jest najlepsza alternatywa dla AutoMappera, która nie ma tego problemu?
+0

Klucz główny wydaje się być podwójnym sprawdzanym odnośnikiem za pomocą 'ThreadSafeList _typeMaps'; co sprawia, że ​​myślisz, że nie jest bezpieczny dla wątków? Czego *** konkretnie *** uważasz, że nie jest bezpieczny dla wątków? –

+0

Czy TypeMap jest niezmiennym obiektem? –

+0

ty mi powiedz! (i pytania są również: nawet jeśli nie jest, czy jest niewłaściwie aktualizowany w jakimkolwiek punkcie, innym niż przez ciebie). Stwierdziłeś, że nie jest bezpieczny dla wątków; proszę wyjaśnij, co według Ciebie nie jest bezpieczne. Zwróć uwagę, że zazwyczaj strategia (raz zbudowana) nie jest aktualizowana, więc jedyną rzeczą wymagającą ochrony jest dostęp do pamięci podręcznej strategii, która wydaje się być wykonana poprawnie. –

Odpowiedz

32

prowadzi link issue mniej więcej odpowiada na pytania:

Mapper.CreateMap threadsafe nie jest, ani nie będzie ona nigdy nie będzie. Jednak Mapper.Map jest bezpieczny dla wątków. Klasyfikacja statyczna klasy Mapper jest tylko cienką otoczką na wierzchu obiektów MappingEngine i Configuration.

więc używać tylko Mapper.CreateMap jeśli zrobić swoją konfigurację w jednym centralnym miejscu w THREADSAFE sposób.

Twój komentarz był:

Pytam tego powodu chciałbym skonfigurować automatter w miejscu, czyli tuż przed użytkowania. Planowałem skonfigurować go w kontekście nie współbieżnym: , tj. ~ Lock (mapperConfigLock) {Mapper.CreateMap() ....; }, i obawiam się, że to nie wystarczy.

Jeśli konfigurujesz w miejscu, po prostu nie używaj statycznej klasy Mapper. Jako komentarz w tej sprawie github sugerują skorzystać z mechanizmu mapowania bezpośrednio:

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); 

To trochę więcej kodu, ale można tworzyć własne pomocników wokół niego. Ale wszystko jest lokalne w danej metodzie, więc żaden wspólny stan nie musi martwić się o bezpieczeństwo wątków.

+0

Wyczyść, wielkie dzięki! –

+0

"jedno centralne miejsce w sposób bezpieczny dla nitek" - myślę, że i tak trzeba to wyjaśnić w tej kwestii, ponieważ jest wiele miejsca na ewentualne błędy. –

+0

@nemesv - wielkie dzięki, twoje rozwiązanie jest naprawdę pomocne! – Ronnix

0

To pytanie może być trochę nieaktualne, chcę tylko nagrać niektóre z moich ustaleń po drobiazgowym śledztwie.

Mapper jest klasa wrapper owinąć aby utworzyć nową konfigurację, a nowa instancja odwzorowującym wewnętrznej pamięci statycznej, więc ściśle rzecz biorąc nie jest bezpieczny wątku, ale można użyć to bezpieczne tak długo, jak tylko zainicjować konfigurację raz .

MapperConfiguration Utwórz nową instancję programu odwzorowującego i zapisz konfigurację wewnątrz własnego obszaru pamięci instancji.

TLDR;

Jeśli trzeba init konfigurację tylko raz, wybierz statycznej API

Jeśli trzeba init konfiguracyjnych wiele razy, i martwić się o bezpieczeństwo wątku, wybierz instancji API

Powiązane problemy