2012-11-21 6 views
31

Ich habe heute von AutoMapper 2.0.0 auf 2.2.0 aktualisiert und festgestellt, dass das Update einige Code kaputt gemacht hat. Wollte hier nachfragen, bevor es als Problem auf der AutoMaker Github-Seite veröffentlicht wird.Ist dies eine bahnbrechende Änderung zwischen AutoMapper 2.0.0 und 2.2.0?

Einer meiner Zieltypen initialisiert eine Sammlung Eigenschaft wie folgt:

public class PageOf<TModel> 
{ 
    public PageOf() 
    { 
     Items = Enumerable.Empty<TModel>(); 
    } 

    public IEnumerable<TModel> Items { get; set; } 
} 

Mit AutoMapper 2.0.0, das war in Ordnung. Als ich auf 2.2.0 aktualisiert habe, verursachte die Zuordnung zu diesem Zieltyp eine NotSupportedException mit der Meldung "Die Sammlung hatte eine feste Größe". (Diese Ausnahme wurde innerhalb eines AutoMapperMappingException gewickelt.)

ich in der Lage war, das Problem zu beheben, indem Sie den Konstruktor-Code über diese Veränderung:

public PageOf() 
{ 
    Items = new List<TModel>(); 
} 

Es scheint, als ob AutoMapper 2.0.0 wurde verworfen, was Wert war in der Items-Eigenschaft und unter Verwendung des set Property Accessor, während AutoMapper 2.2.0 nur den get Property Accessor verwendet und versucht, das vorhandene IEnumerable zu ändern. Es sieht so aus, als ob Enumerable.Empty<TModel>() nur ein Array der Länge Null ersetzt, was die Ausnahme erklären würde.

Ist das ein Fehler? Was wurde in AutoMapper zwischen 2.0.0 und 2.2.0 geändert, sodass der Zieleigenschaften-Setter ignoriert wird und stattdessen versucht wird, die vorhandene Sammlung zu ändern?

Update:

Wie gewünscht, hier ist der CreateMap Aufruf:

public class PagedQueryResultToPageOfItemsProfiler : Profile 
{ 
    protected override void Configure() 
    { 
     CreateMap<PagedQueryResult<EstablishmentView>, PageOfEstablishmentApiModel>(); 
    } 
} 

Die PageOfEstablishmentApiModel Klasse erbt von PageOf<EstablishmentApiModel>. Hier

ist der Mapper.Map Code:

var query = Mapper.Map<EstablishmentViewsByKeyword>(input); 
var results = _queryProcessor.Execute(query); 
var model = Mapper.Map<PageOfEstablishmentApiModel>(results); // exception here 

Wenn eine spezielle Mapping-Konfiguration notwendig (for example .ConvertUsing(x => x)) in AutoMapper ist von 2.0.0 bis 2.2.0 gehen, müssen wir auf die alte Version hängen kann. Mir hat es immer gefallen, wie AM die Eigenschaften der Sammlung automatisch umwandelt, und ansonsten scheint AM eher ValueInjecter zu sein.

+0

Können Sie Ihren Automapper-Code auch posten? zB: 'Mapper.Map' Methodenaufrufe (verwenden Sie generische Methoden?). Dies ist wahrscheinlich "von Entwurf" und leicht zu Ihrem alten Verhalten mit der richtigen Mapper-Methode oder Mapper-Konfiguration zurückgesetzt. Sie können ein Array aus AutoMapper zurückgeben und es Ihrer IEnumerable-Eigenschaft wie in den Dokumenten auf GitHub zuweisen. Ich werde ein oder zwei Beispiele als Antwort veröffentlichen, sobald ich Ihren Code sehe, der die Karte ausführt. – BenSwayne

+2

Es sieht nicht so aus, als würdest du hier viel Glück bekommen. Ich schlage vor, Sie fragen in der [AutoMapper Mailingliste] (https://groups.google.com/forum/?fromgroups#!forum/automapper-users) - dort hängen die Experten rum :) – Mightymuke

+0

Haben Sie sich den AutoMapper 2.2 angesehen? .0 Unterstützung für Rückwärtskompatibilität? Es gibt Fälle, in denen Funktionen/Funktionen von einem Produkt abgekündigt werden (nicht mehr unterstützt) und neue Versionen Apps refactoring erfordern. – G21

Antwort

1

Haben Sie die Karte Methode, die Art und Weise zu nutzen versucht: Mapper.Map<DestinationClass, SourceClass>(object to convert)

?

Mit der 2.2 Version von AutoMapper, das ist, wie wir es verwenden, und es funktioniert gut für uns.

+2

Ja, wenn Sie den Code in der Frage lesen, das ist was ich tue. – danludwig

+0

Entschuldigung, ich habe meine Antwort bearbeitet, weil die generischen Typen nicht angezeigt wurden. Wollte fragen, ob Sie beim Aufruf der Map-Methode die Quellklasse und die Zielklasse angegeben haben. –

0

Ich vermute, dass es versucht, zu Ihrer Sammlung hinzuzufügen, aber da Ihre Sammlung eine readonly-Instanz (Enumerable.Empty<T>) ist, kann es nicht tatsächlich ändern. Ich nehme an, dass Sie richtig sind, dass AutoMapper den Code änderte, wie sie den neuen Typ instanziiert. Verwenden Sie stattdessen eine veränderbare Instanz wie new List<T>() oder T[].

+0

Ich glaube nicht, dass 'T []' veränderbar ist. Das ist, was 'Enumerable.Empty ' standardmäßig verwendet. – danludwig

+0

Aber es kann geändert/mutiert werden, im Gegensatz zu der Enumerable.Empty <T> Referenz, die schreibgeschützt ist. – Haney

+0

Bei der letzten Überprüfung konnte die Größe von Arrays nach der Erstellung nicht geändert werden. Sie haben eine feste Länge. Sie können ein Array in eine Liste konvertieren, seine Größe ändern und es dann in ein anderes Array zurück konvertieren, aber Sie können die Größe eines Arrays nicht direkt ändern. – danludwig