[英]Automapping using open generics and including the source in a ForMember statement
I've recently upgraded from Automapper 4.2.1 to 5.1.1 and am having issues with a previously valid mapping involving open generics. 我最近从Automapper 4.2.1升级到5.1.1,并且遇到了涉及开放泛型的先前有效映射的问题。
Previously, within the automapper configuration, I had the following open generic mapping configuration 以前,在automapper配置中,我有以下开放的通用映射配置
CreateMap(typeof(IPager<>), typeof(ModelPager<>))
.ForMember("Items", e => e.MapFrom(o => (IEnumerable) o));
This works in Automapper 4 but fails in 5 with a InvalidOperaionException
when attempting to map via IMapper.Map<TDestination>(source)
. 这在Automapper 4中有效,但在尝试通过
IMapper.Map<TDestination>(source)
进行映射时,在5中因InvalidOperaionException
而失败。 It appears to fail when executing the mapping of the Items ForMember
operation with an exception message of " Sequence contains no matching element " 在执行Items
ForMember
操作的映射时,它似乎失败,并显示“ Sequence contains no matching element ”的异常消息
As reflected in the example implementation code below IPager<TSource>
implements IEnumerable<TSource>
, and the Items
property of ModelPager<TDestination>
is an IEnumerable<TDestination>
so the cast should be valid. 如下面的示例实现代码所示,
IPager<TSource>
实现IEnumerable<TSource>
, ModelPager<TDestination>
的Items
属性是IEnumerable<TDestination>
因此IEnumerable<TDestination>
应该是有效的。 and there exist a valid mapping for each TSource
to TDestination
并且存在每个
TSource
到TDestination
的有效映射
CreateMap<TSource, TDestination>();
IPager interface IPager界面
public interface IPager<out TItem> : IEnumerable<TItem>
{
int CurrentPage { get; }
int PageCount { get; }
int PageSize { get; }
int TotalItems { get; }
}
IPager implementation 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 ModelPager
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; }
}
What is the proper way to map this in Automapper 5 without either abandoning open generics by explicitly mapping each possible mapping, or by using a custom open generic type converter that would require me to manually map all properties and use reflection to resolve the open types for assignment? 在Automapper 5中通过显式映射每个可能的映射放弃开放泛型 ,或者使用自定义开放泛型类型转换器 ,需要我手动映射所有属性并使用反射来解析开放类型,在Automapper 5中映射它的正确方法是什么分配?
Given this looks to be a bug ( AutoMapper #1624 ), a work around can be done with a custom open generic TypeConverter
that does not require reflection. 鉴于这看起来是一个错误( AutoMapper#1624 ),周围可以用自定义开放式泛型来完成工作
TypeConverter
不需要反思。
The mapping should be changed to something along the lines of 映射应该改为某些行
CreateMap(typeof(IPager<>), typeof(ModelPager<>))
.ConvertUsing(typeof(PagerToModelPagerConverter<,>));
with a custom ITypeConverter
使用自定义
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.