2011-10-24 17 views
8

Przeczytałem zagnieżdżoną stronę wiki odwzorowania, ale wydaje się ona nie pasować do wielu poziomów zagnieżdżania. Mam utworzone następujące mapy i zdefiniowane klasy.Mapowanie zagnieżdżone Automappera

AutoMapper.Mapper.CreateMap<Address, AddressDTO>(); 
AutoMapper.Mapper.CreateMap<MatchCompanyRequest, MatchCompanyRequestDTO>(); 

public class MatchCompanyRequest 
{ 
    Address Address {get;set;} 
} 

public class MatchCompanyRequestDTO 
{ 
    public CompanyInformationDTO {get;set;} 
} 

public class CompanyInformationDTO {get;set;} 
{ 
    public string CompanyName {get;set;} 
    public AddressDTO Address {get;set;} 
} 

Ale następujący kod ...

// works 
matchCompanyRequestDTO.companyInformationDTO.Address = 
    AutoMapper.Mapper.Map<Address, AddressDTO>(matchCompanyRequest.Address); 

// fails 
matchCompanyRequestDTO = 
    AutoMapper.Mapper 
     .Map<MatchCompanyRequest, MatchCompanyRequestDTO>(matchCompanyRequest); 

Czy ten głęboki gniazdowania pracę i mam to skonfigurowane nieprawidłowo? Czy tego rodzaju zagnieżdżanie nie jest jeszcze obsługiwane?

- Edycja

Dla wszystkich zainteresowanych, nie jestem w kontroli DTOs.

Odpowiedz

6

Brakuje mapowania z adresu do CompanyInformationDTO, ponieważ obiekty te znajdują się na tym samym poziomie zagnieżdżenia.

Mapa jest stworzony dla MatchCompanyRequest ->MatchCompanyRequestDTO, ale nie jest w stanie zorientować się, czy to może map Address do CompanyInformationDTO.

więc MatchCompanyRequestDTO mógłby w rzeczywistości mają taką samą deklarację jako swojej CompanyInformationDTO:

public class MatchCompanyRequestDTO 
{ 
    public string CompanyName {get;set;} 
    public AddressDTO Address {get;set;} 
} 

To oczywiście tylko wpływa na Ciebie, jeśli chcesz korzystać z automatycznego mapowania. Nadal można skonfigurować mapy ręcznie, ale wydaje się, że DTOs powinna być ustalona, ​​a nie, spróbujmy tak czy owak:

public class CustomResolver : ValueResolver<Address, CompanyInformationDTO> 
{ 
    protected override CompanyInformationDTO ResolveCore(Address source) 
    { 
     return new CompanyInformationDTO() { Address = Mapper.Map<Address, AddressDTO>(source) }; 
    } 
} 
// ... 

AutoMapper.Mapper.CreateMap<MatchCompanyRequest, MatchCompanyRequestDTO>() 
    .ForMember(dest => dest.companyInformationDTO, opt => opt.ResolveUsing<CustomResolver>().FromMember(src => src.Address)); // here we are telling to use our custom resolver that converts Address into CompanyInformationDTO 
+0

Jak coś takiego być skonfigurowany jeśli nie używasz statycznego Instancja 'Mapper'? – dougajmcdonald

+0

Następnie wystarczy użyć swojej instancji zamiast "AutoMapper.Mapper"? Naprawdę nie wiem - lata minęły, odkąd używałem AutoMappera ... – Bartosz

+0

Tak, najlepszą praktyką w dzisiejszych czasach jest utworzenie profilu i wprowadzenie go do konfiguracji, dzięki czemu można go DI, a nie używać statycznych instancji. Jestem ciekawy, ponieważ widzę to jako powszechne rozwiązanie i zastanawiam się, w jaki sposób pasuje do obecnej najlepszej praktyki. – dougajmcdonald

0

Rozważmy następujący zamiast:

public class MatchCompanyRequest 
{ 
    Address Address {get;set;} 
} 

public class MatchCompanyRequestDTO 
{ 
    public string Name {get;set;} 
    public AddressDTO Address {get;set;} 
} 

public class AddressDTO 
{ 
    .... 
} 

obiektami DTO muszą mieć takie same struktura jako obiekt domeny dla domyślnych konwencji mapowania do pracy w AutoMapper.

Spójrz na to: https://github.com/AutoMapper/AutoMapper/wiki/Projection Wyjaśnimy Projekcję dla Ciebie, możesz dostosować ją tak, aby działała tak, jak masz.

4

Ważne jest, aby określić, jak głębsza jest Twoja nawigacja, aby rozwiązać problemy ze stackoverflow. Wyobraź sobie taką możliwość:

Masz 2 podmioty Użytkownicy i Powiadomienia w modelu NxN (i masz DTOs obiekt do reprezentowania tego), kiedy auto użytkownik odwzorowujący bez ustawiony MaxDepth w ty Mapper wyrażenie "Huston mamy problem " :).

Poniższy kod przedstawia sposób obejścia problemu dla wszystkich twórców map. Jeśli chcesz, możesz go zdefiniować dla każdego programu odwzorowującego.Like this Question

Rozwiązanie 1 (Global Definicja)

public class AutoMapperConfig 
{ 
    public static void RegisterMappings() 
    { 
     Mapper.Initialize(mapperConfiguration => 
     { 
      mapperConfiguration.AddProfile<DomainModelToYourDTOsMappingProfile>(); 
      mapperConfiguration.AddProfile<YourDTOsToDomainModelMappingProfile>(); 
      mapperConfiguration.AllowNullCollections = true; 
      mapperConfiguration.ForAllMaps 
      (
       (mapType, mapperExpression) => 
       { 
        mapperExpression.MaxDepth(1); 
       }); 
      }); 
     } 
    } 

Rozwiązanie 2 (dla każdej Mapper)

public class AutoMapperConfig 
{ 
    public static void RegisterMappings() 
    { 
     Mapper.CreateMap<User, DTOsModel>() 
       .MaxDepth(1); 
    } 
} 
+1

To nie jest poprawna odpowiedź na PO, ale to naprawdę dobra informacja. Dzięki! – Mathter

+0

Thank You @Mathter! –

Powiązane problemy