AutoMapper ForAllMaps отменяет пользовательские настройки - PullRequest
0 голосов
/ 29 октября 2019

В следующем примере (исполняемый в LinqPad) MyString становится «Hello World».

Однако, если я раскомментирую cfg.ForAllMaps, тогда это просто «Hello», очевидно, он переопределяет любые пользовательские настройки.

Я надеюсь использовать cfg.ForAllMaps для установки набора общих правил, например, свойство, которое существует в источнике с дико отличным именем от назначения, но следует общему шаблону, т.е. Person_Age в Source DTO,соответствует свойство Age для целевого типа с именем Person, а Animal_Age соответствует Animal.Age и т. д. Кроме того, тип Person может иметь определенные настройки, которые я хотел бы сделать.

ForAllMaps предназначен для переопределения всехдругие настройки? Если это так, возможно ли использовать его так, как я надеюсь, то есть иметь базовую конфигурацию, которую можно переопределить? Или есть альтернативный API, который я должен использовать (я искал, но пока ничего не нашел)?

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;
    }
}

Дополнительная информация:

В качестве отступления здесьэто функция, которую я выполняю внутри 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");
});

Чтобы прояснить, мой основной вопрос касается того, переопределяет ли ForAllMaps CreateMap () и есть ли способ заставить оба работать хорошовместе мой вторичный пример может отвлекать.

...