Automapper, AfterMap не запускается при отображении на существующий объект, если упоминается ConstructUsing - PullRequest
0 голосов
/ 10 июля 2019

Я столкнулся с проблемой, когда AfterMap не запущен.

Вот условия возникновения этой проблемы:

  • Я хочу отобразить значения существующего объекта из его абстрактного базового типа
  • ConstructUsing предоставляется, как здесь, где будет выбран конкретный тип

Здесь весь тест xunit (после выполнения dotnet new xunit -o PbAutoMapper):

using System;
using AutoMapper;
using Xunit;

namespace PbAutoMapper
{
    public class UnitTest1
    {
        [Fact]
        public void Test1()
        {
            var mapperConfig = new MapperConfiguration(config =>
            {
                config.CreateMap<SourceClass, BaseDestinationClass>()
                    .ConstructUsing(this.Construct)
                    .ForMember(i => i.MyNewProperty, o => o.Ignore())
                    .AfterMap(this.AfterMap);
                config.CreateMap<SourceClass, DestinationClass>();
            });
            var mapper = mapperConfig.CreateMapper();
            var src = new SourceClass { MyProperty = 1 };
            var dest = mapper.Map<BaseDestinationClass>(src);
            Assert.Equal("1", dest.MyNewProperty); // This works...
            dest = new DestinationClass();
            mapper.Map(src, dest);
            Assert.Equal("1", dest.MyNewProperty); // This failed because AfterMap wasn't triggered
        }
        private DestinationClass Construct(SourceClass s, ResolutionContext ctx)
        {
            var d = new DestinationClass();
            ctx.Mapper.Map(s, d, ctx);
            return d;
        }
        private void AfterMap(SourceClass s, BaseDestinationClass d)
        {
            d.MyNewProperty = s.MyProperty.ToString();
        }
    }
    public class SourceClass
    {
        public int MyProperty { get; set; }
    }
    public abstract class BaseDestinationClass
    {
        public string MyNewProperty { get; set; }
    }
    public class DestinationClass : BaseDestinationClass
    {
    }
}

Примечание: этот код, который кажется реализуемым по-другому, на самом деле слишком упрощен, чтобы раскрыть мою проблему самым простым способом.

...