Tuesday, July 24, 2012

Automapper upper and lower case properties mapping

Yesterday I face some sort of common problem: mapping an class to another one (a DTO).
The first class was a generated entity using Entity Framework 4.
The database is a legacy one, and of course untouchable and the name of the columns are are all upper case.
To map these entities to a DTO class, I'm using best tool for .NET on the way: I'm talking about AutoMapper of course.
As you probably know, AutoMapper is a convention-based object-object mapping library.
In a basic usage, AutoMapper maps your property automatically to another one, if the property have the same name.
In my case this convection (the default one) doesn't work because of the upper-case properties, different by the properties of the DTO.

The solution.

AutoMapper, as said is convention based, so you have simply to say to it, to consider one said of the mapping with upper-case property.

How to do it?
First of all write your Naming Convention class:
public class UppercaseNamingConvenction : INamingConvention
{
   private static readonly Regex _splittingExpression
         = new Regex("(\\p{Lu}0-9]+)");

   #region Implementation of INamingConvention

   public Regex SplittingExpression
   {
      get { return _splittingExpression; }
   }

   public string SeparatorCharacter
   {
      get { return string.Empty; }
   }

   #endregion
} 
As you can see, we use a splitting regular expression with a upper case specification.

The next is to define an Automapper profile to specify a different configuration usage.
Write the code below where you configure your application at startup.


Mapper.CreateProfile("first_profile"
   , expression =>
   {
      expression.SourceMemberNamingConvention
         = new UppercaseNamingConvenction();
   });

Mapper.CreateProfile("second_profile"
   , expression =>
   {
      expression.SourceMemberNamingConvention
         = new UppercaseNamingConvenction();
   });

So you will have two profiles: "first_profile" and "second_profile".
To use this configuration, simple specific the profile when you define a mapping strategy:

Mapper.CreateMap<DtoClass, MyDbEntity>().WithProfile("first_profile");

Of course the strategy is the same if you have lower case properties: you have only to change the regular expression.

Have a nice mapping ;)