web-dev-qa-db-fra.com

Comment utiliser le nouveau IValueResolver d'AutoMapper?

Je ne sais pas comment utiliser la nouvelle interface IValueResolver dans la nouvelle version d'AutoMapper. Je les ai peut-être mal utilisés dans les versions précédentes d'AutoMapper ...

J'ai beaucoup de classes de modèles, certaines d'entre elles sont générées à partir de plusieurs bases de données sur plusieurs serveurs de bases de données, en utilisant sqlmetal.

Certaines de ces classes ont une propriété de chaîne, PublicationCode, qui identifie la publication à laquelle l'abonnement, l'offre ou la facture, ou quoi que ce soit, appartient.

La publication peut exister dans l'un ou l'autre des deux systèmes (l'ancien et le nouveau système), j'ai donc une propriété bool sur les classes de modèle de destination qui indique si la publication est dans l'ancien ou le nouveau système.

En utilisant l'ancienne version (<5?) D'AutoMapper, j'ai utilisé un ValueResolver<string, bool> qui a pris le PublicationCode comme paramètre d'entrée et a renvoyé un bool indiquant l'emplacement de la publication (ancien ou nouveau système).

Avec la nouvelle version (5+?) D'AutoMapper, cela ne semble plus être possible. Le nouveau IValueResolver nécessite une implémentation unique de chaque combinaison de modèles source et de destination que j'ai, où src.PublicationCode doit être résolu en dst.IsInNewSystem.

Suis-je en train d'essayer d'utiliser les résolveurs de valeur de la mauvaise façon? Y a-t-il une meilleure façon? La principale raison pour laquelle j'aimerais utiliser un résolveur est que je préférerais que les services soient injectés dans le constructeur, et ne pas avoir à utiliser DependencyResolver et autres dans le code (j'utilise Autofac).

Actuellement, je l'utilise de la manière suivante:

// Class from Linq-to-SQL, non-related properties removed.
public class FindCustomerServiceSellOffers {
    public string PublicationCode { get; set; }
}

C'est l'une des nombreuses classes de modèles de données que j'ai, qui contient une propriété PublicationCode). Cette classe particulière est mappée à ce modèle de vue:

public class SalesPitchViewModel {
    public bool IsInNewSystem { get; set; }
}

La définition de mappage pour ces deux classes est (où l'expression est une IProfileExpression), les mappages non liés ont été supprimés:

expression.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>()
          .ForMember(d => d.IsInNewSystem, o => o.ResolveUsing<PublicationSystemResolver>().FromMember(s => s.PublicationCode));

Et le résolveur:

public class PublicationSystemResolver : ValueResolver<string, bool>
{
    private readonly PublicationService _publicationService;
    public PublicationSystemResolver(PublicationService publicationService)
    {
        _publicationService = publicationService;
    }

    protected override bool ResolveCore(string publicationCode)
    {
        return _publicationService.IsInNewSystem(publicationCode);
    }
}

Et l'utilisation du mappeur:

var result = context.FindCustomerServiceSellOffers.Where(o => someCriteria).Select(_mapper.Map<SalesPitchViewModel>).ToList();
18
PaddySe

Vous pouvez créer un résolveur de valeur plus général en implémentant IMemberValueResolver<object, object, string, bool> et en l'utilisant dans votre configuration de mappage. Vous pouvez fournir une fonction de résolution de propriété source comme précédemment:

public class PublicationSystemResolver : IMemberValueResolver<object, object, string, bool>
{
    private readonly PublicationService _publicationService;

    public PublicationSystemResolver(PublicationService publicationService)
    {
        this._publicationService = publicationService;
    }

    public bool Resolve(object source, object destination, string sourceMember, bool destMember, ResolutionContext context)
    {
        return _publicationService.IsInNewSystem(sourceMember);
    }
}



cfg.CreateMap<FindCustomerServiceSellOffers, SalesPitchViewModel>()
    .ForMember(dest => dest.IsInNewSystem,
        src => src.ResolveUsing<PublicationSystemResolver, string>(s => s.PublicationCode));
13
Rhumborl