2010-01-31 14 views
15

Parece que IValueFormatter toma un valor de tipo object y devuelve un valor de tipo string, mientras que ValueResolver<TSource, TDestination> toma el valor de cualquier tipo y devuelve un valor de cualquier tipo. Entonces, es más flexible. También existe la cuestión de que, con un ValueResolver, nunca es necesario convertir el origen a un tipo particular; lo define explícitamente en la definición de su clase.¿Por qué AutoMapper tiene un IValueFormatter cuando tiene un ValueResolver mucho más poderoso?

Dado esto, ¿por qué usar IValueFormatter? ¿Hace algo que no se puede hacer con ValueResolver? ¿Estoy entendiendo mal cómo funciona?

Respuesta

13

La gran diferencia es que formateadores se pueden aplicar en el miembro, perfil, tipo y nivel mundial. Entonces puede hacer algo como "ForSourceType.AddFormatter() en un perfil, y ahora blammo! Todos sus decimales ahora aparecen como dinero.Los resólvers son estrictamente para el mapeo de miembros personalizados.

+0

Gracias por su respuesta, Jimmy. ¿Hay alguna documentación sobre cómo usar perfiles? He estado trabajando en la documentación en el sitio codeplex, pero no encontré nada sobre los perfiles. – devuxer

+0

Para responder a mi propia pregunta, encontré un buen ejemplo de cómo usar perfiles: http://mhinze.com/automapper-in-nerddinner/ – devuxer

+2

¡necesito un poco más de blammo! en mi código ... – CRice

0

IValueFormatter es una interfaz, y se puede agregar a sus clases existentes o utilizar junto con la biblioteca de la que salió, parece que ValueResolver es una clase que puede tener un rango más amplio de uso ... En palabras diferentes, IValueFormatter probablemente se usa para ayudarlo a usar sus clases con la biblioteca de la que proviene, mientras que la resolución de valores está diseñada para ayudarlo a usar sus clases en su código.

3

bien, creo que he descubierto esto:

  • Con una IValueFormatter, la entrada para el método FormatValue() es el valor real. (De acuerdo, técnicamente, es un objeto ResolutionContext que le permite obtener el valor usando la propiedad SourceValue, pero se entiende).

  • Con un ValueResolver, la entrada al método ResolveCore() es la fuente completa (no solo el valor de origen).

Por lo tanto, si desea hacer algún tipo de conversión entre un valor de origen y un valor de destino, un IValueFormatter sólo funcionará si el tipo de destino es un string, y una ValueResolver sólo funcionará si el método ResolveCore() "sabe" qué propiedad utilizar (que no será el caso si su resolver es de propósito general, es decir, no se aplica a una propiedad en particular).

Solución

Afortunadamente, siempre hay MapFrom, que proporciona la flexibilidad que le falta tanto con resolutores y formateadores.

interfaz Convertidor

terminé escribiendo una interfaz para manejar de forma sencilla y flexible lo que creo que es un escenario muy común: las conversiones de dos vías ...

public interface ITwoWayConverter<TInput, TOutput> 
{ 
    TOutput ConvertForward(TInput value); 
    TInput ConvertBackward(TOutput value); 
} 

Ejemplo convertidor:

public class PhoneNumberToString : ITwoWayConverter<long, string> 
{ 
    public string ConvertForward(long value) 
    { 
     return string.Format("{0:(###) ###-####}", Convert.ToInt64(value)); 
    } 

    public long ConvertBackward(string value) 
    { 
     return Convert.ToInt64(Regex.Replace(value, @"\D", string.Empty)); 
    } 
} 

exampl uso del correo:

Mapper.CreateMap<User, UserViewModel>() 
    .ForMember(dest => dest.PhoneNumber, opt => opt 
     .MapFrom(orig => new PhoneNumberToString().ConvertForward(orig.PhoneNumber))); 
Cuestiones relacionadas