Wystąpiły pewne poważne problemy z automapper. Myślę, że znalazłem rozwiązanie, ale nie wiem, jak go wdrożyć.Używanie wersji CreateMap i Map z usługą WCF za pomocą instancji?
zasadniczo używam niestandardowego mapowania z ResolveUsing i ConstructedBy, aby przekazać parametry konstruktorowi, rozumiem, że większość ludzi ustawiła to raz w global.asax i zapomniała o tym.
Ale problemem jest to, że moja metoda (na WCF) przechodzi w różnych params do konstruktora z ResolveUsing ......
Przed używałem Mapper.CreateMap i Mapper.Map które są statyczne metody i wydaje się, że gdy różne petycje wchodzą do usługi wcf za pośrednictwem metod (multi-user), są ze sobą sprzeczne.
Po przeczytaniu czegoś pojawia się możliwość użycia wersji CreateMap i Map w wersji instancji, dzięki czemu każda indywidualna petycja otrzymuje własną mapę i może przekazywać własne parametry.
Ale nie mogę znaleźć sposobu na zrobienie tego. Czy ktoś może wyjaśnić proszę? Naprawdę utknąłem ...
Przede wszystkim otrzymywałbym zduplikowane błędy klucza, a także wstawiałem ślad dziennika na konstruktorze i wygląda na to, że 1 petycja nadpisuje drugą - stąd statyczne wersje Mappera.
No mam nadzieję, że jestem poprawne, ale nie mogę znaleźć nic innego ...
EDYCJI - przykładem tego, co mam
Zasadniczo wszystko mapowanie działa tak jak powinien, jak Używam MapFrom w większości przypadków.
Następnie tworzę instancję mojego Resolvera, którą przekazuję pod adres URL. Sprawdziłem adres URL, zanim go podaję i jest on poprawny. Ale po zwróceniu zwraca nieprawidłowy adres URL.
Powodem, dla którego muszę podać URL jest to, że zawiera on zmienne, więc muszę wymienić zmienne ... Zasadniczo istnieją 2 adresy URL w zależności od biura i mam dzienniki wszędzie i mogę zobaczyć, co jestem przechodzi, ale kiedy go minie - to nie jest ten, który minąłem, jeśli to ma sens, to jest dziwne !!
Jest to usługa WCF, a klient nazwał tę metodę dwukrotnie w dwóch różnych biurach, stąd 2 różne adresy URL. Ale zawsze zwracają ten sam adres URL. To tak, jakby jedna sesja nadpisała drugą ...
Mam nadzieję, że to ma sens.
SalesPointResolver newSalesPointResolver = new SalesPointResolver(returnReservationUrl, reservationSite.ReservationUrl, startDate, endDate, officeCode);
Mapper.CreateMap<Models.Custom.House, DTO.House>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.TaxIncluded,
opt => opt.MapFrom(src => src.Segments.FirstOrDefault().TaxIncluded))
.ForMember(dest => dest.TaxPercentage,
opt => opt.MapFrom(src => src.Segments.FirstOrDefault().TaxPercentage))
.ForMember(dest => dest.SalesPoints,
opt =>
opt.ResolveUsing(newSalesPointResolver))
;
dowiedział się, gdzie zawodzi - ale wiadomo dlaczego
zobacz moje komentarze inline z kodu. W konstruktorze przychodzi urlTemplate, zapisuję go w prywatnym var, a następnie w przesłoniętym ResolveCore jest coś innego :-)
Umieściłem tam kilka log-logów, więc mogę zobaczyć, co się dzieje.
[Log]
public class SalesPointResolver : ValueResolver<Models.Custom.House, IList<DTO.SalesPoint>>
{
private readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private string urlTemplate;
public SalesPointResolver (bool returnReservationUrl, string urlTemplate, DateTime startDate, DateTime endDate, string officeCode)
{
this.urlTemplate = urlTemplate;
log.Error("passed in " + urlTemplate); // THIS IS PERFECT
log.Error("I am now " + this.urlTemplate); // THIS IS PERFECT
}
protected override IList<DTO.SalesPoint> ResolveCore(House source)
{
this.house = source;
log.Error("in resolveCore :" + this.urlTemplate); // THIS IS RETURNING THE WRONG VALUE
rozwiązanie tymczasowe
Zrobiłem tymczasowe rozwiązanie, ale jest naprawdę źle. Jestem pewien, że automapper może zrobić to, co próbuję, ale oczywiście robię coś nie tak.
Zasadniczo wracam za pośrednictwem LINQ do zbioru rekordów (TO JEST MOJE ŹRÓDŁO), więc wprowadziłem nowe pole do każdego rekordu, w którym znajduje się poprawny szablon adresu URL. A następnie, zamiast przekazywać (poprzez konstruktor) szablon adresu URL, mam go dostępny jako właściwość na KAŻDY rekord w kolekcji (THE SOURCE) ... i działa idealnie.
Oczywiście, to naprawdę jest łatka, a nie idealna, ale działa.
Gdzie się mylę?
W przykładzie jest to, że nie znamy źródła aż do czasu wykonywania ale wiesz, do którego celu mapujesz podczas kompilacji? –
Nie znam źródła ... ale przekazuję zmienne do ResolveUsing przy użyciu konstruktora, dlatego mapa musi być tworzona za każdym razem i nie musi być współużytkowana przez żadną inną sesję itp. –
Jeśli jest to usługa WCF, to działa ona w swoim własna domena aplikacji, więc mapy nie będą udostępniane żadnym innym procesom. Wygląda na to, że argumenty dla ResolveUsing są różne, ale ResolveUsing zwykle przyjmuje typ źródłowy. Jaki jest sens przekazywania argumentów do konstruktora niestandardowego narzędzia Resolver wartości, który jest poza typem źródła? –