2016-08-16 4 views
3

私は最近Automapper 4.2.1から5.1.1にアップグレードし、オープンジェネリックに関する以前の有効なマッピングに問題があります。オープンジェネリックを使った自動マッピングとForMemberステートメントでのソースの追加

以前は、automapper構成内で、私は以下のオープンジェネリックマッピング設定

CreateMap(typeof(IPager<>), typeof(ModelPager<>)) 
    .ForMember("Items", e => e.MapFrom(o => (IEnumerable) o)); 

これはAutomapper 4で動作しますが、IMapper.Map<TDestination>(source)経由でマップしようとしたときにInvalidOperaionExceptionと5に失敗しました。 IPager<TSource>実装IEnumerable<TSource>次の例の実装コード、及びItemsプロパティに反映されるように、例外メッセージをForMember操作

配列が一致する要素を含まない」アイテムのマッピングを実行するときに失敗するように見えますModelPager<TDestination>IEnumerable<TDestination>であるため、キャストは有効である必要があります。各TSource IPagerTDestination

CreateMap<TSource, TDestination>(); 

にインターフェース

public interface IPager<out TItem> : IEnumerable<TItem> 
{ 
    int CurrentPage { get; } 

    int PageCount { get; } 

    int PageSize { get; } 

    int TotalItems { get; } 
} 

IPager実装の有効なマッピングが存在し

public class Pager<TItem> : IPager<TItem> 
{ 
    private readonly IEnumerable<TItem> _items; 

    public Pager(IEnumerable<TItem> items, 
       int currentPage, 
       int pageSize, 
       int totalItems) 
    { 
     /// ... logic ... 
     this._items = items ?? Enumerable.Empty<TItem>(); 
     this.CurrentPage = currentPage; 
     this.PageSize = pageSize; 
     this.TotalItems = totalItems; 
    } 

    public int CurrentPage { get; } 

    public int PageCount => (this.TotalItems + this.PageSize - 1)/this.PageSize; 

    public int PageSize { get; } 

    public int TotalItems { get; } 

    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); 

    public IEnumerator<TItem> GetEnumerator() => this._items.GetEnumerator(); 
} 

ModelPager

明示的に各可能なマッピングをマッピングすることにより、open genericsを放棄いずれかなしAutomapper 5でこれをマップする適切な方法は何ですか
public class ModelPager<TItem> 
{ 
    public int CurrentPage { get; set; } 

    public IEnumerable<TItem> Items { get; set; } 

    public int PageCount { get; set; } 

    public int PageSize { get; set; } 

    public int TotalItems { get; set; } 
} 

、または手動ですべてのプロパティをマッピングしにリフレクションを使用するために私を必要とするカスタムオープンジェネリックtype converterを使用して、割り当てのためのオープンタイプを解決する?

+2

CreateMap(typeof(IPager<>), typeof(ModelPager<>)) .ConvertUsing(typeof(PagerToModelPagerConverter<,>)); 

の線に沿って何かに変更する必要があり、あなたはGitHubの問題を開くことができますか? –

+1

@JimmyBogardできます – rheone

+1

問題[#1624](https://github.com/AutoMapper/AutoMapper/issues/1624)が送信されました – rheone

答えて

3

これはバグ(AutoMapper #1624)になりそうだ考えると、周りの仕事はは、反射を必要としないこと、オープンジェネリックTypeConverterカスタムを行うことができます。

マッピングこれはバグのように見えるカスタムITypeConverter

public class PagerToModelPagerConverter<TSource, TDestination> : ITypeConverter<IPager<TSource>, ModelPager<TDestination>> 
{ 
    public ModelPager<TDestination> Convert(IPager<TSource> source, 
              ModelPager<TDestination> destination, 
              ResolutionContext context) 
    { 
     var list = source.ToList(); // avoid redundant iterations 
     var itemMapping = context.Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>(list); 

     var modelPager = new ModelPager<TDestination> 
         { 
          CurrentPage = source.CurrentPage, 
          Items = itemMapping, 
          PageCount = source.PageCount, 
          PageSize = source.PageSize, 
          TotalItems = source.TotalItems 
         }; 

     return modelPager; 
    } 
関連する問題