Der*_*ğlu 3 c# domain-driven-design automapper
我有 PagedList 实现,并且尝试使用 AutoMapper 将实体 PagedList 映射到 DTO PagedList。
这是我的界面:
public interface IPagedList<T> : IList<T>
{
PagingInformation Paging { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
这是我的班级实施:
public class PagedList<T> : List<T>, IPagedList<T> //, IList<T>
{
public PagingInformation Paging { get; set; }
public PagedList()
{
}
public PagedList(IEnumerable<T> collection) : base(collection)
{
}
public PagedList(IEnumerable<T> collection, PagingInformation paging) : base(collection)
{
Paging = paging;
}
public PagedList(int capacity) : base(capacity)
{
}
PagingInformation IPagedList<T>.Paging
{
get => Paging;
set => Paging = value;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Automapper 像
public async Task<DomainResult<IPagedList<PositionDto>>> GetPagedListAsync(int pageIndex = 0, int pageSize = 20)
{
return DomainResult<IPagedList<PositionDto>>.Success(_mapper.Map<IPagedList<PositionDto>>(await _positionRepository.GetPagedListAsync(pageIndex, pageSize)));
}
Run Code Online (Sandbox Code Playgroud)
没有映射器配置:我收到以下错误:
映射类型错误。
映射类型:PagedList
1 -> IPagedList1 WestCore.Shared.Collections.Pagination.PagedList1[[WestCore.Domain.Entities.Position, WestCore.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] -> WestCore.Shared.Collections.Pagination.IPagedList1[[WestCore.AppCore.Models.PositionDto, WestCore.AppCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
当我添加CreateMap(typeof(PagedList<>), typeof(IPagedList<>))到 Mapper Pofile 时,出现以下错误:
类型“代理 WestCore.Shared.Collections.Pagination.IPgedList`1[[WestCore.AppCore.Models.PositionDto_WestCore.AppCore_Version=1.0.0.0_Culture=neutral_PublicKeyToken=null]]_WestCore.Shared_Version=1.0.0.0_Culture= 中的方法“get_Item”程序集“AutoMapper.Proxies,Version=0.0.0.0,Culture=neutral,PublicKeyToken=be96cd2c38ef1005”中的中性_PublicKeyToken = null'没有实现。
当我添加CreateMap(typeof(PagedList<>),typeof(IPagedList<>)).As(typeof(PagedList<>));到 Mapper Profile 时,我没有收到错误,但 PagedList 返回空结果集
我不确定我是否缺少PagedList方法的实现或者这是一个配置问题。
编辑:
添加分页信息如下:
public class PagingInformation
{
/// <summary>
/// Gets the index start value.
/// </summary>
/// <value>The index start value.</value>
public int IndexFrom { get; }
/// <summary>
/// Gets the page index (current).
/// </summary>
public int PageIndex { get; }
/// <summary>
/// Gets the page size.
/// </summary>
public int PageSize { get; }
/// <summary>
/// Gets the total count of the list of type <typeparamref name="TEntity"/>
/// </summary>
public int TotalCount { get; }
/// <summary>
/// Gets the total pages.
/// </summary>
public int TotalPages { get; }
/// <summary>
/// Gets the has previous page.
/// </summary>
/// <value>The has previous page.</value>
public bool HasPreviousPage => PageIndex - IndexFrom > 0;
/// <summary>
/// Gets the has next page.
/// </summary>
/// <value>The has next page.</value>
public bool HasNextPage => PageIndex - IndexFrom + 1 < TotalPages;
public PagingInformation(int pageIndex, int pageSize, int indexFrom, int count)
{
if (indexFrom > pageIndex)
{
throw new ArgumentException($"indexFrom: {indexFrom} > pageIndex: {pageIndex}, must indexFrom <= pageIndex");
}
PageIndex = pageIndex;
PageSize = pageSize;
IndexFrom = indexFrom;
TotalCount = count;
TotalPages = (int) Math.Ceiling(TotalCount / (double) PageSize);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢
您不能使用接口作为映射的结果,因为映射器不知道如何创建它。
您可以使用 ConstructUsing 创建 IPgedList。像这样:
AutoMapper.Mapper.CreateMap<DtoParent, ICoreParent>()
.ConstructUsing(parentDto => new CoreParent())
.ForMember(dest => dest.Other, opt => opt.MapFrom(src => AutoMapper.Mapper.Map<DtoChild, ICoreChild>(src.Other)));
Run Code Online (Sandbox Code Playgroud)
编辑:
这样工作:
class Example
{
static void Main()
{
AutoMapper.Mapper.Initialize(config =>
{
config.CreateMap(typeof(PagedList<>), typeof(IPagedList<>))
.ConvertUsing(typeof(Converter<,>));
config.CreateMap<Entity, DTO>();
});
var entityList = new PagedList<Entity>(new [] { new Entity(), }, new PagingInformation() { Total = 2, PageNumber = 1, PageSize = 10});
var mapped = Mapper.Map<IPagedList<DTO>>(entityList);
}
}
class Converter<TSource, TDest> : ITypeConverter<IPagedList<TSource> , IPagedList<TDest>>
{
public IPagedList<TDest> Convert(IPagedList<TSource> source, IPagedList<TDest> destination, ResolutionContext context) => new PagedList<TDest>(context.Mapper.Map<IEnumerable<TDest>>(source.AsEnumerable()), source.Paging);
}
class Entity
{
public Guid Id { get; set; } = Guid.NewGuid();
}
class DTO
{
public Guid Id { get; set; } = Guid.NewGuid();
}
public interface IPagedList<T> : IList<T>
{
PagingInformation Paging { get; set; }
}
public class PagingInformation
{
public int Total { get; set; }
public int PageSize { get; set; }
public int PageNumber { get; set; }
}
public class PagedList<T> : List<T>, IPagedList<T>
{
public PagingInformation Paging { get; set; }
public PagedList() { }
public PagedList(IEnumerable<T> collection) : base(collection) { }
public PagedList(IEnumerable<T> collection, PagingInformation paging) : base(collection) { Paging = paging; }
}
Run Code Online (Sandbox Code Playgroud)
也可能需要以某种其他方式映射 PagingInformation,如在我的示例中,两个分页列表都在映射后引用一个 PagingInformation 对象,我认为在 PagingInformation 不可变之前这是可以的。