First, the project is using the clean architecture, the root of my problems is the clean architecture, the "messy" way I don't have half the problems I've been facing, but I need to learn it... Everything I'm implementing here works without the clean architecture, the hard part is adapting the codes.
Outbursts aside...
After implementing the pagination with headers that apparently needs a special type of list containing the pagination data, the automapper just presents me with errors.
In the infrastructure layer I have a generic repository (I disagree a little with the use of repositories but whoever told me to study clean architecture told me to do it that way)
public IQueryable<T> Get()
{
return _context.Set<T>().AsNoTracking();
}
public async Task<PagedList<T>> GetAsync(PagingParameters parameters, Expression<Func<T, object>> orderByExpression)
{
var query = Get();
if (orderByExpression != null)
{
query = query.OrderBy(orderByExpression);
}
var count = await query.CountAsync();
var items = await query
.Skip((parameters.PageNumber - 1) * parameters.PageSize)
.Take(parameters.PageSize).ToListAsync();
return new PagedList<T>(items, count, parameters.PageNumber, parameters.PageSize);
}
CategoryRepository exists and inherits this generic repository but has no specific methods.
In the application layer I have services (and their interfaces) and DTOs, in this case for categories.
In CategoryServices I have this code that is connected to the previous code from the repository:
public async Task<PagedList<CategoryDTO>> GetCategories(PagingParameters parameters)
{
Expression<Func<Category, Object>> orderByExpression;
switch (parameters.OrderedBy.ToLower())
{
case "name":
orderByExpression = x => x.Nome;
break;
default:
orderByExpression = x => x.Id;
break;
}
var categoriesEntity = await _categoryRepository.GetAsync(parameters, orderByExpression);
// Debugging, the error happens here:
return _mapper.Map<PagedList<CategoryDTO>>(categoriesEntity);
}
PagingParameters has paging values, in it I can also inform a string that defines the order of the list as ID or name (that's why the switch case for linq expressions).
Finally in CategoriesController I have a Get action which has a metadata to add the pagination data to the header for the consumer software to use.
[HttpGet]
public async Task<ActionResult<PagedList<CategoriaDTO>>> Get([FromQuery] PagingParameters parameters)
{
var categorias = await _categoriaService.GetCategorias(parameters);
// Header for pagination
var metadata = new
{
categorias.TotalCount,
categorias.PageSize,
categorias.CurrentPage,
categorias.TotalPages,
categorias.HasNext,
categorias.HasPrevious
};
Response.Headers.Add("X-Pagination", JsonSerializer.Serialize(metadata));
return Ok(categorias);
}
This is the PagedList:
namespace Store.Domain.Pagination
{
public class PagedList<T> : List<T>
{
public int CurrentPage { get; set; }
public int TotalPages { get; set; }
public int PageSize { get; set; }
public int TotalCount { get; set; }
public bool HasPrevious => CurrentPage > 1;
public bool HasNext => CurrentPage < TotalPages;
public PagedList(List<T> items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
AddRange(items);
}
Before adding the pagedlist I used the return with IEnumerable, which worked perfectly, after adding the pagedlist I have been getting error like:
Error mapping types.
The mapping for category looks like this:
CreateMap<Category, CategoryDTO>().ReverseMap();
I tried creating a mapping for the pagedlist:
Like this:
CreateMap(typeof(PagedList<Category>), typeof(PagedList<CategoryDTO>));
And like this (but this just dont work lmao, but i tryed):
CreateMap<typeof(PagedList<Category>), typeof(PagedList<CategoryDTO>)>();
But when I try to create a mapping involving the PagedList I get this error:
"Incorrect number of arguments supplied for call to method 'Store.Application.DTOs.CategoryDTO get_Item(Int32)' (Parameter 'property')"
Tried to create a DTO for PagedList and mapped:
CreateMap(typeof(PagedList<Category>), typeof(PagedListDTO<CategoryDTO>));
But when I try this I get an error asking for an empty constructor in the PagedList, but even doing that the error persists.