How to use Ignore globally in AutoMapper?

2019-07-16 04:12发布

Here is how it looks like right now. DestinationA and DestinationB are derived from some DestinationBase class. And I need to ignore some common properties for all these derived class. Is there anyway to apply these ignore options globally without having to repeat for all derived destination classes?

Mapper.CreateMap<SourceA, DestinationA>()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

Mapper.CreateMap<SourceB, DestinationB>()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

I am expecting something like this:

Mapper.CreateMap<DestinationBase>().ForAllSource()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

4条回答
神经病院院长
2楼-- · 2019-07-16 05:03

There's now a method FindTypeMapFor which makes this extension method even smaller (and more efficient?):

public static IMappingExpression<TSource, TDestination> IgnoreAllNonMapped<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        foreach (var property in Mapper.FindTypeMapFor<TSource, TDestination>().GetUnmappedPropertyNames())
        {
            expression.ForMember(property, opt => opt.Ignore());
        }
        return expression;
    }
查看更多
对你真心纯属浪费
3楼-- · 2019-07-16 05:03

See the IgnoreAllNonExisting() extension by schdr here:
AutoMapper: "Ignore the rest"?

public static IMappingExpression<TSource, TDestination> 
    IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
    var sourceType = typeof (TSource);
    var destinationType = typeof (TDestination);
    var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
    foreach (var property in existingMaps.GetUnmappedPropertyNames())
    {
        expression.ForMember(property, opt => opt.Ignore());
    }
    return expression;
}

Usage:

Mapper.CreateMap<SourceType, DestinationType>()
                .IgnoreAllNonExisting();
查看更多
别忘想泡老子
4楼-- · 2019-07-16 05:03

You can ignore all unmapped properties globally. Although this contradict the main benefit of automapper, allows to make explicit mapping only: This is for Automapper 6:

    var mapperConfiguration = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile(new MyProfile());
        // ignore all unmapped properties globally
        cfg.ForAllMaps((map, exp) => exp.ForAllOtherMembers(opt => opt.Ignore()));
    });
查看更多
We Are One
5楼-- · 2019-07-16 05:10

I had the same issue and came across this old question while searching for help. I ended up coming up with the following solution. Maybe it's helpful to someone else...

I have several classes derived from a base class. I want to exclude a property of that base class from all mappings of any class that derives from the base. After creating my mappings (and without specifying any ignore options), I do this:

foreach(var map in Mapper.GetAllTypeMaps())
{
    if (typeof(MyBaseClass).IsAssignableFrom(map.DestinationType))
    {
        var propInfo = map.DestinationType.GetProperty("PropertyToIgnore");
        if (propInfo != null) {
            map.FindOrCreatePropertyMapFor(new AutoMapper.Impl.PropertyAccessor(propInfo)).Ignore();
        }
    }
}

It's a little brute force because I have to loop through all the type maps, but it gets the job done.

edit: Added a missing { to the if statement

查看更多
登录 后发表回答