自动映射器-忽略IEnumerable< SelectListItem>的所有项目. [英] Automapper - ignore all items of IEnumerable<SelectListItem>

查看:69
本文介绍了自动映射器-忽略IEnumerable< SelectListItem>的所有项目.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Automapper是否仍然会忽略某个类型的所有属性?我们正在尝试通过验证Automapper映射来提高代码质量,但必须为始终手动创建的所有IEnumerable<SelectListItem>放置.Ignore()会产生摩擦并减慢开发速度.

Is there anyway of Automapper to ignore all properties of a certain type? We are trying to improve the quality of our code by validating the Automapper mappings but having to put an .Ignore() for all IEnumerable<SelectListItem> which are always manually created is creating friction and slowing down development.

有什么想法吗?

创建映射后可能的想法:

Possible Idea after creating mappings:

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

推荐答案

Automapper当前不支持基于类型的属性忽略.

当前有三种忽略属性的方法:

Currently there is three ways to ignore properties:

  • 在创建映射时使用Ignore()选项

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

这就是您要避免的事情.

this is what you want to avoid.

使用IgnoreMapAttribute

如果您的IEnumerable<SelectListItem>属性名称遵循某些命名约定.例如.它们都以"Select"开头,您可以使用AddGlobalIgnore方法来全局忽略它们:

If your IEnumerable<SelectListItem> property names follow some naming convention. E.g. all them start with the word "Select" you can use the AddGlobalIgnore method to ignore them globally:

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

但是与此您只能匹配以.开头.

but with this you can only match with starts with.

但是,您可以为第一个选项创建一个便利扩展方法,当您调用CreateMap时,该方法将自动忽略给定类型的属性:

However you can create a convinience extension method for the first options which will automatically ignore the properties of a given type when you call 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;
    }
}

您可以通过以下方式使用它:

And you can use it with the following way:

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

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

So it still won't be a global solution, but you don't have to list which properties need to be ignored and it works for multiple properties on the same type.

如果您不怕弄脏自己的手,

当前有一个非常棘手的解决方案,它深入到Automapper的内部.我不知道此API的公开程度,因此该解决方案可能会削弱该功能:

There is currently a very hacky solution which goes quite deep into the internals of Automapper. I don't know how public is this API so this solution might brake in the feature:

您可以订阅ConfigurationStoreTypeMapCreated事件

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

并直接在创建的TypeMap实例上添加基于类型的忽略:

and add the type based ignore directly on the created TypeMap instances:

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

这篇关于自动映射器-忽略IEnumerable&lt; SelectListItem&gt;的所有项目.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆