gpt4 book ai didi

generics - 使用开放泛型进行自动映射并将源代码包含在 ForMember 语句中

转载 作者:行者123 更新时间:2023-12-03 06:22:41 25 4
gpt4 key购买 nike

我最近从 Automapper 4.2.1 升级到 5.1.1,并且之前涉及开放泛型的有效映射出现问题。

以前,在自动映射器配置中,我有以下开放通用映射配置

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

这在 Automapper 4 中有效,但在 5 中失败,并显示 InvalidOperaionException当尝试通过 IMapper.Map<TDestination>(source) 进行映射时。执行 Items ForMember 的映射时似乎失败操作时出现异常消息“序列不包含匹配元素

如下面的示例实现代码所示 IPager<TSource>实现IEnumerable<TSource> ,以及Items ModelPager<TDestination>的属性(property)是 IEnumerable<TDestination>所以 Actor 阵容应该是有效的。并且每个 TSource 都存在一个有效的映射至TDestination

CreateMap<TSource, TDestination>();

IPager界面

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

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; }
}

在 Automapper 5 中映射此内容而不放弃 open generics 的正确方法是什么?通过显式映射每个可能的映射,或使用自定义开放通用 type converter这需要我手动映射所有属性并使用反射来解析要分配的开放类型?

最佳答案

鉴于这看起来是一个错误 ( AutoMapper #1624 ),可以使用不需要反射的自定义开放式通用 TypeConverter 来解决此问题。

映射应该更改为类似的内容

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

使用自定义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;
}

关于generics - 使用开放泛型进行自动映射并将源代码包含在 ForMember 语句中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38983309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com