Подтвердить что ты не робот

Automapper - игнорировать все элементы IEnumerable <SelectListItem>

Есть ли в любом случае Automapper игнорировать все свойства определенного типа? Мы пытаемся улучшить качество нашего кода, проверяя сопоставления Automapper, но для размещения .Ignore() для всех IEnumerable<SelectListItem>, которые всегда создаются вручную, создается трение и замедляется развитие.

Любые идеи?

Возможная идея после создания сопоставлений:

    var existingMaps = Mapper.GetAllTypeMaps();
    foreach (var property in existingMaps)
    {
        foreach (var propertyInfo in property.DestinationType.GetProperties())
        {
            if (propertyInfo.PropertyType == typeof(List<SelectListItem>) || propertyInfo.PropertyType == typeof(IEnumerable<SelectListItem>))
            {
                property.FindOrCreatePropertyMapFor(new PropertyAccessor(propertyInfo)).Ignore();
            }
        }
    }
4b9b3361

Ответ 1

В настоящее время Automapper не поддерживает игнорирование свойств на основе типов.

В настоящее время существует три способа игнорировать свойства:

  • Используйте параметры Ignore() при создании сопоставления

    Mapper.CreateMap<Source, Dest>()
        .ForMember(d => d.IgnoreMe, opt => opt.Ignore());
    

    это то, чего вы хотите избежать.

  • Обозначьте свои свойства IEnumerable<SelectListItem> с помощью IgnoreMapAttribute

  • Если ваши имена свойств IEnumerable<SelectListItem> соответствуют определенному соглашению об именах. Например. все они начинаются со слова "Select", вы можете использовать метод AddGlobalIgnore, чтобы игнорировать их глобально:

    Mapper.Initialize(c => c.AddGlobalIgnore("Select"));
    

    но с этим вы можете соответствовать только с началами.

Однако вы можете создать метод расширения удобства для первых параметров, который автоматически игнорирует свойства данного типа, когда вы вызываете CreateMap:

public static class MappingExpressionExtensions
{
    public static IMappingExpression<TSource, TDest> 
        IgnorePropertiesOfType<TSource, TDest>(
        this IMappingExpression<TSource, TDest> mappingExpression,
        Type typeToIgnore
        )
    {
        var destInfo = new TypeInfo(typeof(TDest));
        foreach (var destProperty in destInfo.GetPublicWriteAccessors()
            .OfType<PropertyInfo>()
            .Where(p => p.PropertyType == typeToIgnore))
        {
            mappingExpression = mappingExpression
                .ForMember(destProperty.Name, opt => opt.Ignore());
        }

        return mappingExpression;
    }
}

И вы можете использовать его следующим образом:

Mapper.CreateMap<Source, Dest>()
    .IgnorePropertiesOfType(typeof(IEnumerable<SelectListItem>));

Таким образом, он по-прежнему не будет глобальным решением, но вам не нужно указывать, какие свойства нужно игнорировать, и он работает для нескольких свойств одного и того же типа.

Если вы не боитесь заразиться руками:

В настоящее время существует очень хакерское решение, которое довольно глубоко проникает во внутренние области Automapper. Я не знаю, насколько общедоступен этот API, поэтому это решение может тормозить в функции:

Вы можете подписаться на событие ConfigurationStore TypeMapCreated

((ConfigurationStore)Mapper.Configuration).TypeMapCreated += OnTypeMapCreated;

и добавьте игнорируемый тип непосредственно в созданных экземплярах TypeMap:

private void OnTypeMapCreated(object sender, TypeMapCreatedEventArgs e)
{
    foreach (var propertyInfo in e.TypeMap.DestinationType.GetProperties())
    {
        if (propertyInfo.PropertyType == typeof (IEnumerable<SelectListItem>))
        {
            e.TypeMap.FindOrCreatePropertyMapFor(
                new PropertyAccessor(propertyInfo)).Ignore();
        }
    }
}

Ответ 2

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

Mapper.Initialize(cfg =>
{
    cfg.ShouldMapProperty = pi => pi.PropertyType != typeof(ICommand);
});

Я не смотрел, когда это было введено. Похоже, что он заблокирует или разрешит, однако вы отфильтровываете это. См. Это: Конфигурация AutoMapper