自动映射 - 忽略IEnumerable <selectlistitem> </selectlistitem>的所有项目

时间:2013-03-11 11:51:18

标签: automapper

无论如何,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();
            }
        }
    }

2 个答案:

答案 0 :(得分:18)

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

因此它仍然不是一个全局解决方案,但您不必列出需要忽略的属性,它适用于同一类型的多个属性。

如果你不害怕弄脏手:

目前有一个非常hacky的解决方案深入到Automapper的内部。我不知道这个API有多公开,所以这个解决方案可能会在功能中产生影响:

您可以订阅ConfigurationStore的{​​{1}}活动

TypeMapCreated

并直接在创建的((ConfigurationStore)Mapper.Configuration).TypeMapCreated += OnTypeMapCreated; 实例上添加基于类型的ignore:

TypeMap

答案 1 :(得分:1)

如果你现在遇到这个,似乎还有另一种方式。

const obj = { name:'saloon', services:[ { sid:1, offid:20, count:2 }, { sid:2, offid:18, count:1 }, { sid:3, offid:15, count:3 } ] };

const servid = 2;
const offid = 18;
var indexes = [];
obj.services.forEach(function(service, index) {
  if(service.sid === servid && service.offid === offid){
    --service.count;
  }
  if(service.count <= 0)
      indexes.push(index);
});

indexes.reverse().forEach(function(index){
  obj.services.splice(index, 1);
});
console.log(obj);

我没有考虑这是什么时候介绍的。这似乎会阻止或允许您过滤它。 请参阅:AutoMapper Configuration