12

とにかく、特定のタイプのすべてのプロパティを無視する Automapper はありますか? Automapper マッピングを検証してコードの品質を向上させようとしていますが、常に手動で作成される.Ignore()for allIEnumerable<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();
            }
        }
    }
4

2 に答える 2

18

Automapper は現在、型ベースのプロパティの無視をサポートしていません。

現在、プロパティを無視する方法は 3 つあります。

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

    ただし、これで一致できるのは、starts with のみです。

ただし、呼び出し時に特定のタイプのプロパティを自動的に無視する最初のオプションの便利な拡張メソッドを作成できます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 がどの程度公開されているかはわかりません。そのため、このソリューションは機能にブレーキをかける可能性があります。

ConfigurationStoreTypeMapCreatedイベントに登録できます

((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();
        }
    }
}
于 2013-03-11T13:03:39.390 に答える