Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoMapper strings to enum descriptions

Given the requirement:

Take an object graph, set all enum type properties based on the processed value of a second string property. Convention dictates that the name of the source string property will be that of the enum property with a postfix of "Raw".

By processed we mean we'll need to strip specified characters e.t.c.

I've looked at custom formatters, value resolvers and type converters, none of which seems like a solution for this?

We want to use AutoMapper as opposed to our own reflection routine for two reasons, a) it's used extensively throughout the rest of the project and b) it gives you recursive traversal ootb.

-- Example --

Given the (simple) structure below, and this:

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

var tmp2 = new SimpleClass();

Mapper.Map(tmp, tmp2);

we'd expect tmp2's MappedCountry enum to be Country.UnitedStates and the Person property to have a gender of 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
}

Thanks

like image 414
6footunder Avatar asked Aug 11 '10 20:08

6footunder


People also ask

Can AutoMapper map enums?

Alternatively, AutoMapper supports convention based mapping of enum values in a separate package AutoMapper.

How do you convert a string value to a specific enum type in C#?

TryParse() method converts the string representation of enum member name or numeric value to an equivalent enum object. The Enum. TryParse() method returns a boolean to indicate whether the specified string is converted to enum or not. Returns true if the conversion succeeded; otherwise, returns false .

How does AutoMapper work in C#?

AutoMapper in C# is a library used to map data from one object to another. It acts as a mapper between two objects and transforms one object type into another. It converts the input object of one type to the output object of another type until the latter type follows or maintains the conventions of AutoMapper.


1 Answers

I did it with the ValueInjecter, here is the whole thing:

I've added one more prop to the SimpleClass just to show you how it works

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

also in case you need to do it from CountryRaw to MappedCountry you could do it like this:

oo.InjectFrom(new StrRawToEnum().TargetPrefix("Mapped"), o);
like image 60
Omu Avatar answered Sep 28 '22 07:09

Omu