2010-08-11 11 views
5

Dado el requisito:cadenas AutoMapper a ENUM descripciones

toma un gráfico de objetos, establecer todas propiedades de tipo enum basados ​​en el procesado valor de una segunda propiedad de cadena. La convención dicta que el nombre de la propiedad de cadena fuente será el de la propiedad enum con un postfijo de "Raw".

Por procesado queremos decir que tendremos que quitar los caracteres especificados e.t.c.

He visto formateadores personalizados, resolución de valores y convertidores de tipo, ninguno de los cuales parece una solución para esto?

Queremos usar AutoMapper en contraposición a nuestra propia rutina de reflexión por dos razones: a) se usa ampliamente durante el resto del proyecto yb) le da un recorrido recursivo ootb.

- Ejemplo -

Dada la estructura (simple) a continuación, y esto:

var tmp = new SimpleClass 
    { 
     CountryRaw = "United States", 
     Person = new Person { GenderRaw="Male" } 
    }; 

var tmp2 = new SimpleClass(); 

Mapper.Map(tmp, tmp2); 

es de esperar que MappedCountry enumeración de Tmp2 ser Country.UnitedStates y la propiedad de tener una persona género de Gender.Male.

public class SimpleClass1 
{ 
    public string CountryRaw {get;set;} 

    public Country MappedCountry {get;set;} 

    public Person Person {get;set;} 
} 

public class Person 
{ 
    public string GenderRaw {get;set;} 

    public Gender Gender {get;set;} 

    public string Surname {get;set;} 
} 

public enum Country 
{ 
    UnitedStates = 1, 
    NewZealand = 2 
} 

public enum Gender 
{ 
    Male, 
    Female, 
    Unknown 
} 

Gracias

+1

podría mostrar un ejemplo de lo que tiene y lo que usted quiere hacer un mapa – Omu

+0

Claro, post original editado :-) – 6footunder

Respuesta

5

lo hice con la ValueInjecter, aquí es todo el asunto:

He añadido un puntal más a la SimpleClass sólo para mostrar cómo funciona

public class SixFootUnderTest 
{ 
    [Test] 
    public void Test() 
    { 
     var o = new SimpleClass1 
        { 
         CountryRaw = "United States", 
         GenderRaw = "Female", 
         Person = new Person { GenderRaw = "Male" } 
        }; 

     var oo = new SimpleClass1(); 

     oo.InjectFrom(o) 
      .InjectFrom<StrRawToEnum>(o); 
     oo.Person.InjectFrom<StrRawToEnum>(o.Person); 

     oo.Country.IsEqualTo(Country.UnitedStates); 
     oo.Gender.IsEqualTo(Gender.Female); 
     oo.Person.Gender.IsEqualTo(Gender.Male); 
    } 

    public class SimpleClass1 
    { 
     public string CountryRaw { get; set; } 

     public Country Country { get; set; } 

     public string GenderRaw { get; set; } 

     public Gender Gender { get; set; } 

     public Person Person { get; set; } 
    } 

    public class Person 
    { 
     public string GenderRaw { get; set; } 

     public Gender Gender { get; set; } 

     public string Surname { get; set; } 
    } 


    public class StrRawToEnum : LoopValueInjection 
    { 
     protected override bool UseSourceProp(string sourcePropName) 
     { 
      return sourcePropName.EndsWith("Raw"); 
     } 

     protected override string TargetPropName(string sourcePropName) 
     { 
      return sourcePropName.RemoveSuffix("Raw"); 
     } 

     protected override bool TypesMatch(Type sourceType, Type targetType) 
     { 
      return sourceType == typeof(string) && targetType.IsEnum; 
     } 

     protected override object SetValue(object sourcePropertyValue) 
     { 
      return Enum.Parse(TargetPropType, sourcePropertyValue.ToString().Replace(" ", ""), true); 
     } 
    } 

    public enum Country 
    { 
     UnitedStates = 1, 
     NewZealand = 2 
    } 


    public enum Gender 
    { 
     Male, 
     Female, 
     Unknown 
    } 
} 

también en caso de que necesite hacerlo desde CountryRaw a MappedCountry puede hacerlo así:

oo.InjectFrom(new StrRawToEnum().TargetPrefix("Mapped"), o); 
+2

Esto, mi amigo, es una solución muy limpio! Gracias :-). – 6footunder

Cuestiones relacionadas