Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing member in AutoMapper 2.1.265

In AutoMapper 2.0 I used Profiles to configure my mapping. I useSourceMemberNameTransformer and DestinationMemberNameTransformer to match my source and destination property names.

In 2.1.265 these properties are no longer on Profile. Does anyone know why they were removed? But more importantly, how can I duplicate this functionality.

Edit

I've been looking at the SourceMemberNamingConvention and DestinationMemberNamingConvention, but I cannot find any documentation as to how those work. Does anyone have experience using a custom INamingConvention?

Edit 2

Source members are generated from a 3rd party database. Typically they use all lowercase column names with underscores between words. Sometimes they leave out underscores, sometimes they throw in random capitalization.

Destination members try to follow .NET naming conventions as much as possible. Underscores were removed, the first character following the underscore were capitalized. Additional case changes were made to make member names easier to read.

To solve this, I set

SourceMemberNameTransformer = name => name.Replace("_", "").ToUpper()
DestinationMemberNameTransformer = name => name.ToUpper()

Edit 3

More information for people from the future.

I inspected the source to see how INamingConvention is used. The way it is designed it a little misleading. The interface is befined as

public interface INamingConvention
{
    Regex SplittingExpression { get; }
    string SeparatorCharacter { get; }
}

However, AutoMapper does not user the full definition of the interface for both SourceMemberNamingConvention and DestinationMemberNamingConvention

It takes each member of the destination type and applies DestinationMemberNamingConvention.SplittingExpression. It then takes those match parts and calls string.Join using SourceMemberNamingConvention.SeparatorCharacter. It then attempts to match the source type members to the destination type members.

This is a very high level overview of what is does and is not an attempt to describe the full functionality. It is merely meant to show how INamingConvention is used and to show that SourceMemberNamingConvention.SplittingExpression and DestinationMemberNamingConvention.SeparatorCharacter are never used.

If you are unable to transform the destination members using this strategy, then you must manually map the properties as nemesv's answer suggests.

like image 767
cadrell0 Avatar asked Nov 14 '22 09:11

cadrell0


1 Answers

It seams this feature is removed see GitHub.

EDIT Rewrite after question update:

Maybe the built in LowerUnderscoreNamingConvention solves your problem. I've tested with this code:

Mapper.Initialize(c => 
    c.SourceMemberNamingConvention = new LowerUnderscoreNamingConvention());
Mapper.CreateMap<Source, Dest>();
var test = Mapper.Map<Dest>(
    new Source() { test_Another_Prop = "test", test_this_prop = "test" });

Where Source and Dest:

public class Source
{
    public string test_this_prop { get; set; }
    public string test_Another_Prop { get; set; }
    public string test_wronglynamedprop { get; set; }
}

public class Dest
{
    public string TestThisProp { get; set; }
    public string TestAnotherProp { get; set; } 
    public string TestWronglyNamedProp { get; set; }
}

If it doesn't cover all your cases you can check how it's implemented in the source and create your own convetion.

EDIT: After comment:

When the convention doesn't apply you can fall back to manually override the special cases:

Mapper.CreateMap<Source, Dest>()
    .ForMember(d => d.TestWronglyNamedProp, c => c
    .MapFrom(s => s.test_wronglynamedprop));

I see no other option in the current version. Because as far as see nothing replaces the MemberNameTransformers.

like image 167
nemesv Avatar answered Nov 16 '22 03:11

nemesv