2012-03-23 14 views
7

Ich bin mir nicht sicher, ob ich hier ein Threading-Problem habe oder nicht. Beim Laden der Seite führe ich zwei Ajax-Anfragen aus, um einige zusätzliche Daten von einer Drittanbieter-API zu laden. Hier ist, wie jede Methode aussieht, die aufgerufen wird:AutoMapper Threading-Problem (Fehlertyp-Map-Konfiguration oder nicht unterstützte Zuordnung)?

private List<CaseCommentModel> GetCaseCommentModels(string caseId) { 
    var comments = CaseService.GetAllCaseCommentsByCaseId(caseId); 

    Mapper.Reset(); 
    Mapper.CreateMap<CrmCaseComment, CaseCommentModel>(); 

    var caseCommentModels = Mapper.Map<List<CrmCaseComment>, List<CaseCommentModel>>(comments); 

    return caseCommentModels; 
} 

private List<CaseAttachmentModel> GetCaseAttachmentModels(string caseId) { 
    var attachments = AttachmentService.GetAttachmentsByParentId(caseId); 

    Mapper.Reset(); 
    Mapper.CreateMap<CrmAttachment, CaseAttachmentModel>(); 

    var caseAttachmentModels = Mapper.Map<List<CrmAttachment>, List<CaseAttachmentModel>>(attachments); 

    return caseAttachmentModels; 
} 

Manchmal beide Antworten erfolgreich. Aber wenn ich die Seite aktualisieren, manchmal wird man mit der folgenden Ausnahme fehlschlagen:

Missing type map configuration or unsupported mapping

ich von beiden Anfragen gehen kann, ohne irgendwelche Änderungen am Code zu einem Versagen Erfolg; Alles was es braucht ist eine Aktualisierung der Seite. Ist das ein Threading-Problem oder verwende ich den Mapper falsch?

Antwort

5

Sie sollten eine Zuordnung nur einmal pro Anwendungslebensdauer erstellen. Also, verschiebe alle spezifischen CreateMap zum App-Start.

Das Problem, das Sie erleben wahrscheinlich auf das Rennen verwandt ist die Zuordnung vor dem anderen Thread zu tun ruft Mapper.Reset()

10

Ja, Sie ein Threading-Problem haben und Sie die AutoMapper Konfiguration missbräuchlich. Vom AutoMapper getting started page:

Wenn Sie die statische Mapper-Methode sind, die Konfiguration muss nur einmal pro AppDomain passieren. Das bedeutet, dass der beste Konfigurationscode im Anwendungsstart ist, z. B. die Datei Global.asax für ASP.NET-Anwendungen. In der Regel befindet sich die Bootstrapper-Klasse in einer eigenen Klasse, und diese Bootstrapper-Klasse ist , die von der Startmethode aufgerufen wird.

Sie sollten also Mapper.CreateMap nicht innerhalb der Controller-Aktionen haben, verschieben Sie sie an gemeinsamen Ort und führen sie einmal aus.

oder wenn Sie tun dynamische Mapping-Konfiguration verwenden Sie nicht die statische Mapper stattdessen die Config von bauen und den Motor „von Hand“:

var config = 
    new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers()); 
config.CreateMap<CrmCaseComment, CaseCommentModel>(); 
var engine = new MappingEngine(config); 
var caseCommentModels = 
    engine.Map<List<CrmCaseComment>, List<CaseCommentModel>>(comments); 
+0

+1 für dynamische Konfigurationen – zidane

1

stieß ich auf eine Ausgabe Einfädeln und möchten um meine Ergebnisse zu teilen.

In meiner Anwendung in der WCF-Service Constructor Ich rief die AutoMapperRegistry. Konfigurieren Sie(), um die Zuordnungen für den automatischen Zuordner zu erstellen.

Vom MVC-Controller nenne ich den Dienst durch die Singleton-Objekt des WCF-Dienst aufrufen.

Die aktuelle Ausgabe vom Web-Client ist ich tatsächlich asyncrounusly zwei der Controller-Methoden genannt, so dass an den Dienst übermittelt beide und gibt das Ergebnis. Der Moment ich änderte die erste Methode zu Async falsch in dem Problem wurde gelöst.

Grund Wenn beide Methoden aufgerufen werden async die Race-Bedingung tritt und ab und zu, dass durch sie selbst aufgelöst wird manchmal Threading-Problem wird dadurch erzeugt wird, die obige Ausnahme ausgelöst.

0

Ja, Sie haben ein Threading-Problem und die beste Lösung ist (meiner Meinung nach), die statische API von AutoMapper zu stoppen.

Ich schlage vor, Sie AutoMapper in follwoing Weise konfigurieren: // IoC Registrierung (Autofac in meinem Fall)

builder 
    .Register(c => new MapperConfiguration(cfg => { 
     cfg.AddProfile<AutoMapperProfile>(); 
    })) 
    .SingleInstance(); 
builder 
    .Register(c => c.Resolve<MapperConfiguration>().CreateMapper()) 
    .As<AutoMapper.IMapper>(); 

Bitte beachten Sie, dass ich MapperConfiguration als einzige Instanz erstellen. Klasse AutoMapperProfile.cs enthält die Konfiguration des Auto- mapper:

Verwandte Themen