2010-09-20 17 views
8

Mi problema es hidratar un modelo de vista de un objeto Linq2Sql que se ha devuelto de la base de datos. Hemos hecho esto en algunas áreas y tenemos un buen patrón en capas preparado para ello, pero el último elemento requiere que se utilicen algunas enumeraciones y esto ha causado dolores de cabeza en general. Actualmente nos retiramos de la base de datos y luego utilizamos Automapper para hidratar (o aplanar) en nuestros Viewmodels pero parece que las enumeraciones en el modelo están causando problemas con Automapper. Intenté crear resovlers personalizados que fueron suficientes para todos mis otros requisitos de mapeo, pero no funciona en esta instancia.Cadena de mapa a enumeración con Automapper

Una muestra del código es el siguiente:

public class CustomerBillingTabView{ 
    public string PaymentMethod {get; set;} 
    ...other details 
} 

public class BillingViewModel{ 
    public PaymentMethodType PaymentMethod {get; set;} 
    ...other details 
} 

public enum PaymentMethodType { 
    Invoice, DirectDebit, CreditCard, Other 
} 

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType> 
{ 
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source) 
    { 

     if (string.IsNullOrWhiteSpace(source.PaymentMethod)) 
     { 
      source.PaymentMethod = source.PaymentMethod.Replace(" ", ""); 
      return (PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), source.PaymentMethod, true); 
     } 

     return PaymentMethodType.Other; 
    } 
} 

     CreateMap<CustomerBillingTabView, CustomerBillingViewModel>() 
     .ForMember(c => c.CollectionMethod, opt => opt.ResolveUsing<PaymentMethodTypeResolver>()) 

me sale el siguiente error

[ArgumentException: Type provided must be an Enum. 
Parameter name: enumType] 
    System.Enum.TryParseEnum(Type enumType, String value, Boolean ignoreCase, EnumResult& parseResult) +9626766 
    System.Enum.Parse(Type enumType, String value, Boolean ignoreCase) +80 
    AutoMapper.Mappers.EnumMapper.Map(ResolutionContext context, IMappingEngineRunner mapper) +231 
    AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context) +720 

me gustaría seguir con AutoMapper para todas nuestras acciones de mapeo pero he visto Mucha gente dice que no hace este tipo de mapeos, así que estoy empezando a preguntarme si lo estoy usando de forma incorrecta. Además, he visto algunas menciones de ValueInjecter: ¿es esta una alternativa a Automapper, o será útil simplemente tapar los agujeros en Automapper para la hidratación de los modelos y usar Automapper para el aplanamiento?

Sí, podría usar una cadena en mi ViewModel, pero no soy fanático de las cuerdas mágicas, y este elemento en particular lo usan los ayudantes para llevar a cabo cierta lógica en varios lugares.

+0

D'oh después de mirar más de cerca los ejemplos en la fuente y mis modelos I me di cuenta de un par de cosas en primer lugar, por alguna razón, hice que la propiedad enum del null "ViewModel" causara los principales problemas ?? !! La segunda cosa es que no había considerado el espacio en blanco devuelto por nuestra vista "Débito directo" debería haber sido DirectDebit ... Una vez que eliminé estos problemas, Automapper lo hizo sin resolucionadores personalizados, etc. Woo hoo –

+0

+1 por mencionar ValueInjecter;) – Omu

Respuesta

9

Este es un problema con la documentación de AutoMapper. Si descarga la fuente de AutoMapper, hay ejemplos allí. El código que uno quiere tener este aspecto:

public class PaymentMethodTypeResolver : ValueResolver<CustomerBillingTabView, PaymentMethodType> 
{ 
    protected override PaymentMethodType ResolveCore(CustomerBillingTabView source) 
    { 

     string paymentMethod = source.Context.SourceValue as string; 

     if (string.IsNullOrWhiteSpace(paymentMethod)) 
     { 
      paymentMethod = paymentMethod.Replace(" ", ""); 
      return source.New((PaymentMethodType)Enum.Parse(typeof(PaymentMethodType), paymentMethod, true)); 
     } 

     return source.New(PaymentMethodType.Other); 
    } 
} 
+0

Gracias Jason ... Fui a probar tu solución pero no puedo entender de dónde vienen el .Context.SourceValue y el source.New. Me estoy perdiendo algo ... lo siento un poco novato, lo sé. –

+0

Hola Jason Gracias por los consejos, si ves mi comentario anterior, lo solucioné sin la necesidad de una resolución personalizada. Gracias de todos modos y señalarme las muestras fue de gran ayuda –

+0

¡Claro que no hay problema! –

5

he aquí una solución con el ValueInjecter: puesto que ya solucionó el problema que sólo voy a apuntar a algo similar:

AutoMapper strings to enum descriptions

en esta pregunta los requisitos eran un poco más que hacer de cadena es posible enumerar, pero incluye también esta conversión

sobre el ValueInjecter siendo una alternativa: sí, hace cosas más genéricas sin configuración para cada pequeña cosa requerida, y construye cualquier convención que puedas imaginar

+0

Saludos por eso lo echaré un buen vistazo. –

Cuestiones relacionadas