1

I simply need to map some auto generated classes from database to domain/viewmodels classes. The autogenerated class may have names like customer_id that I want to be mapped with CustomerId. Somehow I want to register my own convention with auto mapper. I have started with following code however the mapped object properties are not populated:

  // Generic method that should map source to target
  public static TTarget MapWithUnderScoreConvension(TSource source, TTarget target)
    {
        Mapper.Initialize(cfg=> cfg.AddProfile<AutoMapperUnderScoreProfile>());
        Mapper.CreateMap<TSource, TTarget>();
        var mapped = Mapper.Map(source, target);
        return mapped;
    } 

 // New underscore profile
public class AutoMapperUnderScoreProfile : Profile
{
    public AutoMapperUnderScoreProfile()
    {
        Mapper.Initialize(configuration => configuration.CreateProfile("UnderScoreProfile", UnderScoreProfile));
        Mapper.AssertConfigurationIsValid();
    }

    private void UnderScoreProfile(IProfileExpression profile)
    {
        profile.SourceMemberNamingConvention = new PascalCaseNamingConvention();
        profile.DestinationMemberNamingConvention = new SourceUnderScoreNamingConvension();
    }
}

// Convention class
public class SourceUnderScoreNamingConvension : INamingConvention
{
    private readonly string _separatorCharacter="_";
    private readonly Regex _splittingExpression = new Regex(@"[\p{Lu}0-9]+(?=_?)");

    public Regex SplittingExpression { get { return _splittingExpression;} private set{} }
    public string SeparatorCharacter { get { return _separatorCharacter; } private set{} }
}

// Test cases
 [TestMethod()]
    public void Test_Map_Db_Generated_Class_To_Model()
    {
        var dbGenerated = new QuestionTypeFromDb()
        {
            QuestionType_Description = "1",
            QuestionType_Id = 1,
            QuestionType_Is_Default = true,
            QuestionType_Is_TimeBased = true,
            QuestionType_Sequence = 1,
            QuestionType_Time_In_Seconds = 1
        };

        var mappedObject = AutoMapperHelper<QuestionTypeFromDb, QuestionType>
            .MapWithUnderScoreConvension(dbGenerated, new QuestionType());

        mappedObject.QuestionTypeId.Should().Be(dbGenerated.QuestionType_Id);
        mappedObject.QuestionTypeDescription.Should().Be(dbGenerated.QuestionType_Description);
        mappedObject.TimeInSeconds.Should().Be(dbGenerated.QuestionType_Time_In_Seconds);
        mappedObject.QuestionTypeSequence.Should().Be(dbGenerated.QuestionType_Sequence);
    }

 public class TestQuestionWithAnswerType 
{
    public int QuestionTypeId { get; set; }
    public string QuestionTypeDescription { get; set; }
    public int QuestionTypeSequence { get; set; }
    public bool QuestionTypeIsTimeBased { get; set; }
    public int? QuestionTypeTimeInSeconds { get; set; }
    public bool QuestionTypeIsDefault { get; set; }
}

any comments will be appreciated.

Update

I have found that the following workaround works: I simply replaced used this -> to replace 'underscore' with nothing (Mapper.Initialize(c => c.ReplaceMemberName("_", ""));

 public static TTarget MapWithUnderScoreConvension(TSource source, TTarget target)
    {
        Mapper.Initialize(c => c.ReplaceMemberName("_", ""));
        //Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperUnderScoreProfile>());
        Mapper.CreateMap<TSource, TTarget>();
        var mapped = Mapper.Map(source, target);
        return mapped;
    }
gsk
  • 1,233
  • 15
  • 32
user1829319
  • 691
  • 1
  • 8
  • 22

2 Answers2

1

Your regex needs to be changed to : [\p{L}}0-9]+(?=_?)

This will take care of Customer_Id, CUSTOMER_ID, customer_id

The {L} unicode category includes Lu, Lt, Ll, Lm and Lo characters as mentioned here.

gsk
  • 1,233
  • 15
  • 32
  • Hi,thanks for the reply. I changed the regular expression to what you have suggested however still the result is same. I have found a workaround that may not be the best solution but works for me. I will update my question the solution ... – user1829319 Jun 30 '15 at 07:51
0

Answer is added in the Update section of the question. Basically the solution for me was very simple -> Mapper.Initialize(c => c.ReplaceMemberName("_", ""));

user1829319
  • 691
  • 1
  • 8
  • 22