J'ai eu de vrais problèmes avec automapper. Je pense avoir trouvé la solution mais je ne sais pas comment l'implémenter.Utilisation de la version d'instance de CreateMap et de Map avec un service WCF?
Fondamentalement, j'utilise un mappage personnalisé avec ResolveUsing et ConstructedBy pour passer des params au constructeur, je comprends que la plupart des gens le définissent une fois dans le global.asax et l'oublient.
Mais le problème est que ma méthode (sur un WCF) passe dans différents params au constructeur d'un ResolveUsing ......
Avant que j'utilisais le Mapper.CreateMap et Mapper.Map qui sont méthodes statiques et il apparaît que lorsque différentes pétitions entrent dans le service wcf via des méthodes (multi-utilisateurs), elles sont en conflit les unes avec les autres. Après avoir lu quelque chose, il semble que je puisse utiliser la version d'instance de CreateMap et Map pour que chaque pétition obtienne sa propre carte et puisse transmettre ses propres paramètres.
Mais je n'arrive pas à trouver comment le faire. Quelqu'un peut-il expliquer s'il vous plaît? Je suis vraiment coincé ...
Avant et encore j'obtiendrais des erreurs de clé en double et aussi j'ai mis dans une trace de journal sur le constructeur et il apparaît que 1 pétition remplace l'autre - d'où les versions statiques de Mapper.
Eh bien, j'espère que je ne me trompe pas, mais je ne trouve rien d'autre ...
ÉDITÉE - UN EXEMPLE DE CE QUE JE DOIS
Fondamentalement, tout ce mapping fonctionne comme il se doit, comme J'utilise MapFrom dans la plupart des cas.
Ensuite, je crée une instance de mon résolveur que je passe dans une URL. J'ai vérifié l'URL avant de la transmettre et c'est correct. Mais une fois qu'il retourne, il renvoie la mauvaise URL.
La raison pour laquelle je dois passer dans l'URL est qu'elle contient des variables, donc j'ai besoin de remplacer les variables ... Fondamentalement, il y a 2 urls selon le bureau et j'ai des journaux partout et je vois ce que je suis passant mais une fois que je le passe - ce n'est pas celui que j'ai passé, si cela a du sens, c'est bizarre !!
C'est un service WCF et un client a appelé la méthode deux fois en passant dans 2 bureaux différents donc 2 URL différentes. Mais ils retournent toujours la même URL. C'est comme si une session écrasait l'autre ...
J'espère que cela a du 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))
;
TROUVE où ne parvient pas - en ligne avec le code MAIS POURQUOI UNKNOWN
Voir mes commentaires. Dans le constructeur, l'urlTemplate arrive, je l'enregistre dans un var privé puis dans le ResolveCore surchargé c'est autre chose :-)
J'ai placé quelques logs log4net là-bas, donc je peux voir ce qui se passe.
[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
SOLUTION TEMPORAIRE
je l'ai fait une solution temporaire, mais il est vraiment mauvais. Je suis sûr que automapper peut faire ce que j'essaie, mais je fais évidemment quelque chose de mal. Fondamentalement, je retourne par LINQ une collection d'enregistrements (c'est ma source) donc j'ai entré un nouveau champ sur chaque enregistrement qui a le bon modèle d'URL là-bas. Et puis, au lieu de passer (via le constructeur) le template de l'url, je l'ai disponible comme propriété sur TOUT enregistrement sur la collection (LA SOURCE) ... et ça marche parfaitement.
Bien sûr, c'est vraiment patch et pas idéal mais ça me fait courir.
Où est-ce que je me trompe?
Dans votre exemple, est-ce que vous ne connaissez pas la source jusqu'à l'exécution mais savez-vous à quelle cible vous correspondez au moment de la compilation? –
Non, je connais la source ... mais je passe des variables à ResolveUsing en utilisant le constructeur, donc la map doit être créée à chaque fois et ne doit pas être partagée par une autre session –
S'il s'agit d'un service WCF, il fonctionne propre domaine de l'application pour que les cartes ne soient partagées avec aucun autre processus. Il semble que les arguments de ResolveUsing varient, mais ResolveUsing prend typiquement le type source. Quel est le raisonnement pour que vous passiez des arguments dans le constructeur de votre Value Resolver personnalisé qui sont en dehors de votre type source? –