Ist Mapper.Anzeigen in AutoMapper thread-safe?
Ich bin auf der Suche bis AutoMapper code jetzt (Auswertung für eines der Projekte an dem ich arbeite), und, offen gesagt das sprechen, ich bin ziemlich überrascht:
- Die Bibliothek API basiert auf einer einzelnen statischen access-point (
Mapper
- Typ), so dass in der Regel jede der Methoden muß thread-sicher - Aber ich fand keine Beweise, die dafür in code.
Alle die ich finden konnte, ist dieses Problem, aber auch die Aussage gemacht, es scheint falsch: wenn Map
nicht thread-safe Datenstrukturen intern, kann es nicht als thread-sicher, da auch, wenn ich dabei bin, rufen Sie CreateMap
im nicht-gleichzeitigen Kontext, aber gleichzeitig mit Map
.
I. e. die einzig mögliche Nutzungsmuster von AutoMapper, z.B. ASP.NET MVC-Anwendung ist:
lock (mapperLock) {
... Mapper.AnyMethod(...) ...
}
Offensichtlich, wenn ich richtig bin, das ist ein großer Mangel.
Also ich habe zwei Fragen:
- Bin ich richtig?
- Wenn ja, was ist die beste alternative zu AutoMapper nicht dieses Problem haben?
- Das wichtigste scheint zu sein, das double-checked-lookup über
ThreadSafeList<TypeMap> _typeMaps
; was macht Sie denken, es ist nicht thread-sicher? Was ist speziell glauben Sie nicht thread-safe? - Ist TypeMap ein immutable-Objekt?
- sagen Sie mir! (und das Fragen ist auch: selbst wenn es nicht ist, ist es unangemessen aktualisiert an jedem Punkt, außer von Ihnen). Sie haben eine Forderung, es ist nicht thread-sicher sind; bitte erläutern Sie auf, was Sie denken, ist nicht sicher. Beachten Sie, dass in der Regel die Strategie, die (einst) nicht aktualisiert, so dass die einzige Sache, die Schutz braucht, ist der Zugang zu den Strategie-cache, die angezeigt wird, um richtig gemacht werden.
- Hi Alex, verwenden Sie EmitMapper! )
- Sie suchen den code jetzt einmal mehr. Eigentlich habe ich die Verwendung von
ThreadSafeList
es. - Bin ich richtig, dass
TypeMap
Eintrag rechts aufMapper.CreateMap
nennen, und weiter modifiziert durchIMappingExpression
Methoden? Wenn ja, gibt es ein Problem, da die gleichzeitige Threads zugreifen können inkonsistenteTypeMap
während es geändert wird von einem thread aufrufenCreateMap
. - re CreateMap: ist es nicht nur Hinzugefügt, um die Liste am Ende der Konstruktion?
- Ich denke, diese Frage ist völlig gültig. Wir können nicht davon ausgehen, die Bibliothek thread-sicher, da haben wir nicht gefunden, Beweise gegen ihn. Es ist anders herum: alles ist unsicher, bis das Gegenteil bewiesen ist. Ich denke, der Autor dieser lib braucht, um Schritt in.
- Um vollständig zu erklären, der Fall: ich Frage dies, weil ich möchte, zu konfigurieren automatter in-place, D. H. direkt vor der Verwendung. Ich geplant, um Sie zu konfigurieren, die in nicht-gleichzeitigen Kontext, d.h. ~
lock (mapperConfigLock) { Mapper.CreateMap()....; }
, und ich fürchte, das ist nicht genug jetzt. - Siehe z.B. diesen test code: github.com/AutoMapper/AutoMapper/blob/master/src/UnitTests/... - ich kann mir nicht vorstellen, wie
TypeMap
es kann Hinzugefügt werden, nachdem dieCreateMap
nennen. Ich vermute, der Eintrag wird direkt auf diesen Aufruf, und geändert durchForMember
-wie Methoden weiter. - Ok, einen genauen code von Automapper:
public void ConvertUsing(Type typeConverterType) { Type type = ...; this._typeMap.UseCustomMapper ...; }
- Noch ein Beispiel:
private void ForDestinationMember(...) { this._propertyMap = this._typeMap.FindOrCreatePropertyMapFor(destinationProperty); ...
- Bezüglich der thread-Sicherheit von Automapper: IMO, die Frage ist wichtig. Es ist eines der am meisten beachteten Projekte auf C# auf GitHub mit allen Konsequenzen.
- Dies ist einer der Gründe, warum ich freue mich auf Umzug in deutlich instanziiert Konfiguration - um diese Art von Dinge, die "offensichtlich".
- Wird behoben werden in 3.2.0 github.com/AutoMapper/AutoMapper/issues/473
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den verlinkten Problem mehr oder weniger Antworten auf Ihre Fragen:
Also nur verwenden
Mapper.CreateMap
wenn Sie Ihre Konfiguration in einem zentralen Ort in einem threadsicher Weise.Dein Kommentar war:
Wenn Sie tun, in-place-Konfiguration einfach nicht die statische
Mapper
Klasse. Wie der Kommentar auf der github-Ausgabe empfehlen die Verwendung der mapping-engine direkt:Es ist ein bisschen mehr code, aber Sie können erstellen Sie Ihre eigenen Helfer um ihn herum.
Aber alles ist lokal in einer bestimmten Methode, so dass kein gemeinsamer Staat muss sich keine sorgen machen um die thread-Sicherheit.
Diese Fragen kann ein bisschen veraltet, nur aufnehmen möchten, einige meiner Erkenntnisse nach ein wenig Untersuchung.
Mapper ist eine wrapper-Klasse zu wickeln, um neue Konfiguration erstellen, und neue Instanz der mapper im inneren statischen Speicher, also streng genommen ist es nicht thread-sicher, aber Sie können es verwenden, sicher, solange Sie nur initialisieren der Konfiguration einmal.
MapperConfiguration erstellen Sie eine neue Instanz des Mappers, und notieren Sie die config in einer eigenen Instanz Speicherplatz.
TLDR;
Wenn Sie brauchen, um init der Konfiguration nur EINMAL, wählen Sie die statische API
Wenn Sie brauchen, um die init-Konfiguration viele Male, und sorgen über die der thread-Sicherheit, wählen Sie instance-API