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.
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 MemberNameTransformer
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With