2012-11-21 12 views
31

Zaktualizowałem z AutoMappera 2.0.0 do wersji 2.2.0 już dziś i zdałem sobie sprawę, że aktualizacja zepsuła trochę kodu. Chciałem zapytać o to tutaj, zanim opublikujesz jako problem na stronie github automapper.Czy jest to przełomowa zmiana między AutoMapper 2.0.0 i 2.2.0?

Jeden z moich typów docelowych Inicjuje nieruchomość kolekcja tak:

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

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

Z automapper 2.0.0, to było w porządku. Po aktualizacji do wersji 2.2.0 mapowanie do tego typu miejsca docelowego spowodowało wyjątek NotSupportedException z komunikatem "Kolekcja miała ustalony rozmiar". (Wyjątek ten został owinięty wewnątrz AutoMapperMappingException.)

udało mi się rozwiązać ten problem poprzez zmianę kodu konstruktora powyżej to:

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

Wydaje się jakby AutoMapper 2.0.0 został odrzucając cokolwiek wartość była we właściwości Items i przy użyciu właściwości Property accessor, podczas gdy AutoMapper 2.2.0 używa właśnie właściwości dostępu do właściwości get i próbuje zmodyfikować istniejący IEnumerable. Wygląda na to, że Enumerable.Empty<TModel>() po prostu zastępuje tablicę o zerowej długości, która wyjaśniałaby wyjątek.

Czy to błąd? Co zmieniło się w AutoMapper pomiędzy 2.0.0 a 2.2.0, które spowodowałoby zignorowanie ustawienia docelowego i zamiast tego spróbował zmodyfikować istniejącą kolekcję?

Aktualizacja:

Zgodnie z wnioskiem, o to wezwanie CreateMap:

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

Klasa PageOfEstablishmentApiModel dziedziczy PageOf<EstablishmentApiModel>.

Oto kod Mapper.Map:

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

Jeśli specjalnej konfiguracji mapowania jest konieczne (for example .ConvertUsing(x => x)) w AutoMapper począwszy od 2.0.0 do 2.2.0, możemy mieć do powieszenia na starej wersji. Zawsze podobało mi się, w jaki sposób AM automatycznie konwertuje właściwości kolekcji, a bez tego AM wydaje się bardziej podobny do ValueInjecter.

+0

Czy umieścisz swój kod Automapper? tj: wywołania metody 'Mapper.Map' (czy używasz ogólnych metod?). Jest to prawdopodobnie "projektowe" i łatwo można przywrócić stare zachowanie za pomocą właściwej metody odwzorowania lub konfiguracji odwzorowania. Możesz zwrócić tablicę z automappera i przypisać ją do swojej własności IEnumerable, jak w dokumentach na github. Opublikuję przykład lub dwa jako odpowiedź, gdy zobaczę twój kod, który wykonuje mapę. – BenSwayne

+2

Wygląda na to, że nie dostaniesz tutaj szczęścia. Sugeruję, aby zapytać na liście dyskusyjnej [AutoMapper] (https://groups.google.com/forum/?fromgroups#!forum/automapper-users) - tam spotykają się eksperci :) – Mightymuke

+0

Czy dokonałeś wcześniej przeglądu AutoMapper 2.2 .0 wsparcie dla kompatybilności wstecznej? Zdarzają się przypadki, w których funkcje/funkcjonalności są przerywane (nie są już obsługiwane) z produktu, a nowsze wersje wymagają refaktoryzacji aplikacji. – G21

Odpowiedz

1

Czy próbowałeś użyć metody Mapa ten sposób: Mapper.Map<DestinationClass, SourceClass>(object to convert)

?

Dzięki wersji 2.2 AutoMapper, w ten sposób używamy go i działa dobrze dla nas.

+2

Tak, jeśli czytasz kod w pytaniu, to właśnie robię. – danludwig

+0

Przepraszam, edytowałem swoją odpowiedź, ponieważ typy ogólne nie były wyświetlane. Chciał zapytać, czy określasz klasę źródłową i klasę docelową podczas wywoływania metody Map. –

0

Zgaduję, że stara się dodać do swojej kolekcji, ale ponieważ twoja kolekcja jest instancją tylko do odczytu (Enumerable.Empty<T>), nie można jej zmodyfikować. Zakładam, że masz rację, że AutoMapper zmienił kod, w jaki sposób tworzy nowy typ. Zamiast tego użyj zmiennej instancji, takiej jak new List<T>() lub T[].

+0

Nie sądzę, że 'T []' jest zmienne. To właśnie używa domyślnie 'Enumerable.Empty . – danludwig

+0

Ale może być zmieniony/zmutowany, w przeciwieństwie do Enumerable.Empty <T> odniesienie, które jest tylko do odczytu. – Haney

+0

Po ostatnim sprawdzeniu nie można zmienić rozmiaru tablic po ich utworzeniu. Są one na stałe. Możesz przekonwertować tablicę na listę, zmienić jej rozmiar, a następnie przekonwertować ją z powrotem na inną, ale nie możesz bezpośrednio zmienić rozmiaru tablicy. – danludwig