3

AssertConfigurationIsValidメソッドを使用して、マッピング プロファイルの単体テストを行います。マッピングを受け入れるようにするには、マップされていない宛先プロパティを明示的に無視する必要があります。これにより、マッピング コードが汚染され、読みにくくなります。これは、AssertConfigurationIsValid を使用した単体テストに合格するためにのみ必要なので、「無視する」コードを同じ単体テストに移動したいと思います。

いくつかのマッピング プロファイル クラスからの次のマッピング コードを検討してください。

CreateMap<SourceType, DestinationType>()
   // here goes some actual mapping code:
   .ForMember(dest => dest.DestMember, opt => opt.MapFrom(src => src.SourceMember))
   // and then go the explicitly ignored unmapped dest members,
   // just for AssertConfigurationIsValid to pass:
   .ForMember(dest => dest.IgnoredMember, opt => opt.Ignore());

後者のコードを単体テスト メソッドに移動したいので、次のようになります。

[TestMethod]
public void TestMappingConfiguration()
{
  Mapper.AddProfile<MyProfile>();
  Mapper.FindTypeMapFor<SourceType, DestinationType>()
    .ForMember(dest => dest.IgnoredMember, opt => opt.Ignore());
  Mapper.AssertConfigurationIsValid(MyProfile.Name);
}

Mapper クラスには既に FindTypeMapFor メソッドがありますが、無視されたプロパティをマッピングに追加する良い方法が見つかりません。これは可能ですか?

4

2 に答える 2

5

やりたいことができてきました。以下は、無視されたプロパティを既存のマップに追加するための拡張メソッドを持つメイン クラスです。

  static class TypeMapExtensions
  {
    public static TypeMap<TSource, TDestination> AddIgnoredMember<TSource, TDestination>(
      this TypeMap<TSource, TDestination> typeMap, 
      Expression<Func<TDestination, object>> accessorExpression)
    {
      MemberInfo memberInfo = ReflectionHelper.FindProperty(accessorExpression);
      IMemberAccessor memberAccessor = memberInfo.ToMemberAccessor();
      var propertyMap = new PropertyMap(memberAccessor);
      propertyMap.Ignore();
      AddPropertyMap(typeMap.Map, propertyMap);
      return typeMap;
    }

    private static void AddPropertyMap(TypeMap typeMap, PropertyMap propertyMap)
    {
      typeMap.AddPropertyMap(propertyMap);
      if (typeMap.HasDerivedTypesToInclude())
      {
        IEnumerable<TypeMap> derivedMaps = GetDerivedMaps(typeMap);
        foreach (var derivedMap in derivedMaps)
          derivedMap.AddInheritedPropertyMap(propertyMap);
      }
    }

    private static IEnumerable<TypeMap> GetDerivedMaps(TypeMap typeMap)
    {
      return Mapper.GetAllTypeMaps().Where(
        map =>
          (map.Profile == typeMap.Profile) &&
          (typeMap.TypeHasBeenIncluded(map.SourceType, map.DestinationType)));
    }
  }

クラス TypeMap は、元の TypeMap に対するラッパーにすぎません。汎用バージョンのポイントは、流暢な構文を許可することです (以下を参照)。

AutoMapper ソース コードから借用した ReflectionHelper クラス。AutoMapper.Internal 名前空間の他の 5 つのクラスに依存しているため、それらも借用されています。

最後に、これらすべてにより、次のコードを書くことができます。

TypeMap<SourceType, DestinationType>.Get()
  .AddIgnoredMember(dest => dest.IgnoredMember)
  .AddIgnoredMember(dest => dest.AnotherIgnoredMember);
于 2013-04-17T09:15:34.997 に答える
2

最初にすべてのメンバーを無視してから、必要なプロパティに特定のマッピングを提供できますか? これを支援する拡張機能を以前に作成しました。

public static IMappingExpression<TSource, TDest>
    IgnoreAllUnmapped<TSource, TDest>(
        this IMappingExpression<TSource, TDest> expression)
{
    expression.ForAllMembers(opt => opt.Ignore());
    return expression;
}

次に、次のようなことができます

CreateMap<SourceType, DestinationType>()
    .IgnoreAllUnmapped()
    .ForMember(d => d.DestMember, opt => opt.MapFrom(s => s.SourceMember))
于 2013-04-14T22:52:03.940 に答える