In the following example (executable in LinqPad), MyString becomes "Hello World".
However, if I uncomment cfg.ForAllMaps then it is just "Hello", it apparently overrides any custom settings.
I'm hoping to use cfg.ForAllMaps to set a bunch of common rules e.g a property which exists on the source with a wildly different name to the destination but follows a common pattern i.e. Person_Age in a Source DTO, would match the Age property on a destination type called Person and Animal_Age matches Animal.Age etc. On top of this, the Person type may have specific customisations which I'd wish to do.
Is ForAllMaps meant to override all other settings? If so, is it possible to use it in the manner I'm hoping i.e. having a baseline config which can be overridden? Or is there an alternative API I should be using (I've been poking around but not found anything so far)?
void Main()
{
var config = new MapperConfiguration(cfg =>
{
//Uncomment this and ForCtorParam override does not work
// cfg.ForAllMaps((typeMap, map) =>
// {
// });
cfg.CreateMap<Source, Destination>()
.ForCtorParam("myString", x => x.MapFrom(y => $"{y.MyString} World"));
});
config.AssertConfigurationIsValid();
var mapper = config.CreateMapper();
var source = new Source()
{
MyString = "Hello"
};
var dest = mapper.Map<Destination>(source);
dest.Dump();
}
public class Source
{
public string MyString { get; set; }
}
public class Destination
{
public string MyString {get; private set;}
public Destination(string myString)
{
this.MyString = myString;
}
}
Further information:
As an aside here is the sort of function I'm executing inside of the ForAllMaps:
void SetupMemberAndRenamedContructorParameter<T>(TypeMap typeMap, IMappingExpression map, string sourcePropertyName, string destinationPropertyName, string destinationContructorParamaterName)
{
map.ForMember(destinationPropertyName, x => x.MapFrom(sourcePropertyName));
var propertyInfo = (PropertyInfo)typeMap.SourceTypeDetails.PublicReadAccessors.Single(w => w.Name == sourcePropertyName);
Expression<Func<object, T>> getValue = (sourceClassInstance) => (T)propertyInfo.GetValue(sourceClassInstance);
map.ForCtorParam(destinationContructorParamaterName, x => x.MapFrom(getValue));
}
cfg.ForAllMaps((typeMap, map) =>
{
SetupMemberAndRenamedContructorParameter<string>(typeMap, map, $"{typeMap.DestinationType.Name.ToUpper()}_ERROR", "ErrorCode", "errorCode");
SetupMemberAndRenamedContructorParameter<int>(typeMap, map, $"{typeMap.DestinationType.Name.ToUpper()}_RATING", "Flag", "flag");
});
To clarify my primary question is in regard to whether ForAllMaps overrides CreateMap() and whether there is a way to get both to work nicely together, my secondary example may be a distraction.