如何配置Automapper以自动忽略具有ReadOnly属性的属性?

时间:2015-02-07 13:41:12

标签: c# .net asp.net-mvc mapping automapper

上下文:

我们说我有以下"目的地"类:

public class Destination
{
    public String WritableProperty { get; set; }

    public String ReadOnlyProperty { get; set; }
}

和"来源"在其中一个属性上具有ReadOnly属性的类:

public class Source
{
    public String WritableProperty { get; set; }

    [ReadOnly(true)]
    public String ReadOnlyProperty { get; set; }
}

很明显,但要明确:我将按以下方式从Source班级映射到Destination班级:

Mapper.Map(source, destination);

问题:

有哪些方法可以将Automapper配置为自动忽略具有ReadOnly(true)属性的属性?

的约束:

我使用Automapper的Profile类进行配置。我不想弄脏具有Automapper特定属性的类。我不想为每个只读属性配置Automapper,并通过这种方式导致大量重复。

可能(但不适合)的解决方案:

1)将属性IgnoreMap添加到属性:

    [ReadOnly(true)]
    [IgnoreMap]
    public String ReadOnlyProperty { get; set; }

我不想弄脏具有特定于自动播放程序的属性的类,并使其依赖于它。另外,我不想添加其他属性以及ReadOnly属性。

2)配置Automapper忽略属性:

CreateMap<Source, Destination>()
.ForSourceMember(src => src.ReadOnlyProperty, opt => opt.Ignore())

这不是一种方式,因为它迫使我为每个地方的所有财产做到这一点,并且还会造成很多重复。

2 个答案:

答案 0 :(得分:24)

编写扩展方法,如下所示:

public static class IgnoreReadOnlyExtensions
{
    public static IMappingExpression<TSource, TDestination> IgnoreReadOnly<TSource, TDestination>(
               this IMappingExpression<TSource, TDestination> expression)
    {
        var sourceType = typeof(TSource);

        foreach (var property in sourceType.GetProperties())
        {
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(sourceType)[property.Name];
            ReadOnlyAttribute attribute = (ReadOnlyAttribute) descriptor.Attributes[typeof(ReadOnlyAttribute)];
            if(attribute.IsReadOnly == true)
                expression.ForMember(property.Name, opt => opt.Ignore());
        }
        return expression;
    }
}

要调用扩展程序方法:

Mapper.CreateMap<ViewModel, DomainModel>().IgnoreReadOnly();

答案 1 :(得分:8)

现在您还可以使用ForAllPropertyMaps全局禁用它:

configure.ForAllPropertyMaps(map =>
    map.SourceMember.GetCustomAttributes().OfType<ReadOnlyAttribute>().Any(x => x.IsReadOnly),
    (map, configuration) =>
    {
        configuration.Ignore();
    });