State avendo alcuni problemi reali con automapper. Penso di aver trovato la soluzione ma non sono sicuro di come implementarlo.Utilizzo della versione di istanza di CreateMap e Map con un servizio WCF?
fondamentalmente sto usando una mappatura personalizzata con ResolveUsing e ConstructedBy per passare in params al costruttore, capisco che la maggior parte delle persone lo imposta su global.asax una volta e se ne dimentica.
Ma il problema è che il mio metodo (su un WCF) passa in diverse params al costruttore di un ResolveUsing ......
Prima usavo il Mapper.CreateMap e Mapper.Map che sono metodi statici e sembra che quando diverse petizioni entrano nel servizio wcf tramite metodi (multiutente) sono in conflitto tra loro.
Dopo aver letto qualcosa, è possibile utilizzare la versione di istanza di CreateMap e Map in modo che ogni singola petizione ottenga la propria mappa e possa passare i propri parametri.
Ma non riesco a trovare come farlo. Qualcuno può spiegare per favore? Sono davvero bloccato ...
Prima di tanto in tanto ricevevo errori di chiave duplicati e inoltre inserivo una traccia di log sul costruttore e sembra che 1 petizione stia sovrascrivendo l'altra - da qui le versioni statiche di Mapper.
Beh spero ho ragione, ma non riesco a trovare niente altro ...
a cura - un esempio di quello HO
Fondamentalmente tutto mappatura sta funzionando come dovrebbe, come Sto usando MapFrom nella maggior parte dei casi.
Quindi creo un'istanza del mio Resolver che passo in un URL. Ho controllato l'url prima che lo trasmetta e sia corretto. Ma una volta restituito restituisce l'URL sbagliato.
Il motivo per cui ho bisogno di passare nell'URL è che ha delle variabili lì, quindi ho bisogno di sostituire le variabili ... Fondamentalmente ci sono 2 URL a seconda dell'ufficio e ho i log ovunque e posso vedere cosa sono passando dentro ma una volta che l'ho passato - non è quello che ho passato, se questo ha senso, questo è strano !!
Un servizio WCF e un client hanno chiamato il metodo passando due volte in due uffici diversi, quindi 2 URL diversi. Ma restituiscono sempre lo stesso URL. È come se una sessione stesse sovrascrivendo l'altra ...
Spero che abbia senso.
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))
;
scoperto dove sta venendo a mancare - ma sconosciuto PERCHE
Vedere i miei commenti in linea con il codice. Nel costruttore arriva l'urlTemplate, l'ho salvato in una var privata e poi nel sovrascritto ResolveCore è un'altra cosa :-)
Ho inserito alcuni log4net lì, quindi posso vedere che cosa sta succedendo.
[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
soluzione temporanea
ho fatto una soluzione temporanea, ma è davvero male. Sono sicuro che l'automapper può fare ciò che sto provando, ma ovviamente sto facendo qualcosa di sbagliato.
In sostanza, restituisco tramite LINQ una raccolta di record (QUESTA È LA MIA FONTE), quindi ho inserito un nuovo campo in ogni record che contiene il modello di URL corretto. E poi, invece di passare (tramite costruttore) il template dell'URL, l'ho messo a disposizione come proprietà su OGNI record sulla collezione (THE SOURCE) ... e funziona perfettamente.
Ovviamente, questa è davvero una patch e non ideale ma mi fa girare.
Dove sto andando male?
Nel tuo esempio è vero che non si conosce l'origine fino al runtime ma sai a quale target stai mappando al momento della compilazione? –
No so la fonte ... ma sto passando in variabili a ResolveUsing utilizzando il costruttore quindi la mappa deve essere creata ogni volta e non deve essere condivisa da altre sessioni ecc. –
Se questo è un servizio WCF è in esecuzione nel suo il proprio dominio app in modo che le mappe non vengano condivise con altri processi. Sembra che gli argomenti di ResolveUsing varino, ma ResolveUsing prende tipicamente il tipo di sorgente. Qual è il motivo per cui devi passare argomenti nel costruttore del tuo Value Resolver personalizzato che è al di fuori del tuo tipo di sorgente? –