Поддерживает ли AutoMapper Open Generics с наследованием от неуниверсального базового класса?

Номер версии AutoMapper — 7.0.0.

Возьмите следующий набор классов:

public class Person
{
    public string Name { get; set; }
    public List<BarBase> BarList { get; set; }
}

public class PersonModel
{
    public string Name { get; set; }
    public List<BarModelBase> BarList { get; set; }
}

abstract public class BarBase
{
    public int Id { get; set; }
}

public class Bar<T> : BarBase
{
    public T Value { get; set; }
}

abstract public class BarModelBase
{
    public int Id { get; set; }
}

public class BarModel<T> : BarModelBase
{
    public T Value { get; set; }
}

Person имеет свойство BarList типа List<BarBase>. BarBase — это абстрактный класс с общей конкретной реализацией Bar<T>; Список должен содержать несколько типов T.

Следующие две конфигурации работают. Закомментированные разделы не работают, как описано в комментариях.

var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap(typeof(BarBase), typeof(BarModelBase))
       .Include(typeof(Bar<string>), typeof(BarModel<string>));

    cfg.CreateMap(typeof(Bar<string>), typeof(BarModel<string>));
    cfg.CreateMap(typeof(Person), typeof(PersonModel));
});

var config = new MapperConfiguration(cfg =>
{
    //Fails with: System.NullReferenceException : Object reference not set to an instance of an object.
    //cfg.CreateMap(typeof(BarBase), typeof(BarModelBase)).As(typeof(BarModel<>));

    //Fails with:  Missing map from AutoMapper.UnitTests.OpenGenerics+Bar`1[T] to AutoMapper.UnitTests.OpenGenerics+BarModel`1[T]. Create using Mapper.CreateMap<Bar`1, BarModel`1>.
    //cfg.CreateMap(typeof(BarBase), typeof(BarModelBase))
    //   .Include(typeof(Bar<>), typeof(BarModel<>));

    cfg.CreateMap<BarBase, BarModelBase>().ConvertUsing((source, destination, context) =>
    {
        System.Type sourceType = source.GetType();
        System.Type structType = sourceType.GetGenericArguments()[0];

        return (BarModelBase)context.Mapper.Map(source, sourceType, typeof(BarModel<>).MakeGenericType(structType));
    });


    cfg.CreateMap(typeof(Person), typeof(PersonModel));
    cfg.CreateMap(typeof(Bar<>), typeof(BarModel<>));
});

Чтобы убедиться, что любая конфигурация работает:

Person person = new Person
{
    Name = "Jack",
    BarList = new List<BarBase>
    {
        new Bar<string>{ Id = 1, Value = "One" },
        new Bar<string>{ Id = 2, Value = "Two" }
    }
};

PersonModel personMapped = config.CreateMapper().Map<PersonModel>(person);

Assert.Equal("One", ((BarModel<string>)personMapped.BarList[0]).Value);

Проблема: я не могу заставить Open Generics AutoMapper работать для этого сценария (Generic<T> extends Non-Generic) без преобразователя ("ConvertUsing") или путем явного сопоставления каждого из закрытых универсальных типов.

Вопрос: Что я упускаю? - Есть ли готовая конфигурация сопоставления типов, которую я могу использовать здесь без использования конвертера?


person Marx    schedule 06.06.2018    source источник


Ответы (1)


журнал проблем AutoMapper подтверждает, что для этого типа сопоставления в текущей версии необходим преобразователь. версия.

person Marx    schedule 07.06.2018
comment
Попробуйте сборку MyGet. - person Lucian Bargaoanu; 10.06.2018
comment
Апгрейд работает. Спасибо за быстрое обращение. - person Marx; 12.06.2018