net how example createmissingtypemaps c# automapper automapper-5

c# - how - ¿Cómo usar el nuevo IValueResolver de AutoMapper?



automapper nuget (1)

No sé cómo usar la nueva interfaz IValueResolver en la nueva versión de AutoMapper. Tal vez los usé incorrectamente en las versiones anteriores de AutoMapper ...

Tengo muchas clases modelo, algunas de ellas se generan a partir de varias bases de datos en varios servidores de bases de datos, utilizando sqlmetal.

Algunas de estas clases tienen una propiedad de cadena, PublicationCode , que identifica a qué publicación pertenece la suscripción, la oferta, la factura o lo que sea.

La publicación puede existir en cualquiera de los dos sistemas (el antiguo y el nuevo), por lo tanto, tengo una propiedad bool en las clases del modelo de destino que indica si la publicación está en el antiguo o en el nuevo sistema.

Usando la versión anterior (<5?) De AutoMapper, usé un ValueResolver<string, bool> que tomó el PublicationCode como un parámetro de entrada y bool un bool indicaba la ubicación de la publicación (sistema antiguo o nuevo).

Con la nueva versión (5+?) De AutoMapper, esto parece que ya no es posible. El nuevo IValueResolver requiere una implementación única de cada combinación de modelos de origen y destino que tengo, donde src.PublicationCode debe resolverse en un dst.IsInNewSystem .

¿Estoy tratando de usar los resolutores de valor de manera incorrecta? ¿Hay alguna manera mejor? La razón principal por la que me gustaría usar un sistema de resolución es que preferiría que los servicios se inyecten en el constructor, y que no tenga que usar DependencyResolver y similares en el código (estoy usando Autofac).

Actualmente, lo uso de la siguiente manera:

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

Esta es una de las varias clases de modelo de datos que tengo, que contiene una propiedad PublicationCode). Esta clase en particular se asigna a este modelo de vista:

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

La definición de asignación para estas dos clases es (donde expresión es una expresión IProfileExpression), eliminaciones no relacionadas eliminadas:

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

Y el resolvedor:

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); } }

Y el uso del mapeador:

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


Puede crear una resolución de valor más general implementando IMemberValueResolver<object, object, string, bool> y usándolo en su configuración de mapeo. Puede proporcionar una función de resolución de propiedad de origen como antes:

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));