Пользовательское сопоставление объекта с строкой в ​​AutoMapper - PullRequest
0 голосов
/ 09 мая 2018

Использование AutoMapper (v6.2.2, плюс AutoMapper.Extensions.Microsoft.DependencyInjection ) Я хочу использовать существующие системные TypeConverter классы для преобразования из определенных моделей данных в строки.

Хотя внутренний MapperRegistry содержит TypeConverterMapper, который должен иметь возможность делать это автоматически ( без необходимости какой-либо ручной настройки здесь указано здесь ), он никогда не получит Вызывается как StringMapper, имеет приоритет, когда типом назначения является string.

Другие (более старые) ответы предлагают изменить объекты сопоставления в MapperRegistry, но, похоже, с тех пор этот класс был сделан internal.

Могу ли я изменить приоритет (или удалить) различных встроенных классов сопоставления в AutoMapper?


В качестве обходного пути я также попытался создать в своем Profile карту, которая будет пытаться преобразовать любой объект в строку с помощью преобразователей типов:

private class ApiTypeConverter : ITypeConverter<object, string>
{
     public string Convert(object source, string destination, ResolutionContext context)
     {
        TypeConverter sourceTypeConverter = TypeDescriptor.GetConverter(source.GetType());
        if (sourceTypeConverter.CanConvertTo(typeof(string)))
        {
           return (string)sourceTypeConverter.ConvertTo(source, typeof(string));
        }

        return default(string);
     }
}

который я настроил для использования:

CreateMap<object, string>().ConvertUsing<ApiTypeConverter>();

Но это тоже не сработало, как ожидалось. В идеале я бы делал это только для членов, которые можно преобразовать с помощью условия, например:

ForAllMaps((m, e) => e.ForAllMembers(opt => opt.Condition(HasConverter))
                      .ConvertUsing<ApiTypeConverter>());

Однако это невозможно (метод ForAllMembers возвращает void).


Поскольку я использую AutoMapper.Extensions.Microsoft.DependencyInjection Мне удалось использовать параметр additionalInitAction для изменения сопоставителей:

services.AddAutoMapper(InitAction, GetType().Assembly);

private void InitAction(IMapperConfigurationExpression configuration)
{
    var mapper = configuration.Mappers.OfType<StringMapper>().First();
    configuration.Mappers.Remove(mapper);
}

Это привело к тому, что все заработало, как и ожидалось, но кажется немного хаком, поскольку другие карты могут полагаться на StringMapper.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Если используется внедрение зависимостей, конфигурацию можно изменить при добавлении AutoMapper в службы:

services.AddAutoMapper(InitializeMapper, typeof(Startup).Assembly);

Затем добавьте соответствующую инициализацию:

private static void InitializeMapper(IMapperConfigurationExpression cfg)
{
    StringMapper stringMapper = cfg.Mappers.OfType<StringMapper>().First();
    int index = cfg.Mappers.IndexOf(stringMapper);

    cfg.Mappers.Insert(index, new CustomObjectMapper());
}
0 голосов
/ 09 мая 2018

Вы можете использовать configuration.Mappers для изменения списка встроенных картографов, но карта от объекта к строке также должна работать.

Mapper.Initialize(cfg =>
{
    var mappers = cfg.Mappers;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...