0

I was reading following website, and created a PageModel and Specification pattern. Question is should I merge these two for good practice or keep separate? The PageModel will accept following parameters in a URL API, for pagination. So 100 products, one can see 10 products per page .

localhost/api/Products?Page3&Limit=10

https://dejanstojanovic.net/aspnet/2019/january/filtering-and-paging-in-aspnet-core-web-api/

public class PageModel
{
    public int Page { get; set; }
    public int Limit { get; set; }
    public string ColumnSort { get; set; }

    public object Clone()
    {
        var jsonString = JsonConvert.SerializeObject(this);
        return JsonConvert.DeserializeObject(jsonString, this.GetType());
    }
}

Additionally, created specification Pattern which works with company Domain Driven Design (DDD) and generic repository (architect at company wanted generic repository, not my call)

public class Paged<T> : IPaged<T>
{
    private readonly IQueryable<T> source;

    public Paged(IQueryable<T> source)
    {
        this.source = source;
    }

    public IEnumerator<T> GetEnumerator()
    {
        return source.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public int Count
    {
        get { return source.Count(); }
    }

    public IEnumerable<T> GetPage(int index, int limit)
    {
        if (index <= 0 || limit <= 0)
        {
            return source;
        }
        else
        {
            return source.Skip((index - 1) * limit)
                .Take(limit);
        }
    }

    public IEnumerable<T> GetPage(int index, int limit, IEnumerable<string> orderMembers, ListSortDirection sortOrder)
    {
        return source.OrderByMembers(orderMembers, sortOrder)
            .Skip((index - 1) * limit)
            .Take(limit);
    }

    public T GetFirst(Expression<Func<T, bool>> whereLambda)
    {

        return source.Where(whereLambda).FirstOrDefault();
    }

    public IEnumerable<T> GetAll()
    {
        return source.ToList();
    }
}

In reading a bunch of websites, the question is do I still need first PageModel, or is it better to merge it into Page Specification pattern below. It seems like it would clean up/simplify code, not sure if it breaks SRP single responsibility principle.

Realized if they were merged, we would have to place Paged Pattern into URL parameter, it when then expose other methods, not sure if this is safe or not, probably guessing not.

Current implementation:

API Controller

    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<ProductDto>), StatusCodes.Status200OK)]
    public ActionResult<BaseRequestResponse<IEnumerable<ProductDto>>> Get([FromQuery] PageModel pageModel)
    {
        ProductRequest productRequest = new ProductRequest();
        productRequest.pageModel = pageModel;
        return Ok(productAppService.GetAllProducts(productRequest));
    }

App Business Service Layer:

    public IEnumerable<ProductDto> GetAllProducts(ProductRequest productRequest)
    {
        var productspaged = new Paged<Product>(productRepository.GetAll()).GetPage(productRequest.pageModel.Page, productRequest.pageModel.Limit);

        IEnumerable<ProductModel> productModel = mapper.Map<IEnumerable<ProductModel>>(productspaged);
        var productDto = mapper.Map<IEnumerable<ProductModel>, IEnumerable<ProductDto>>(productModel);
        return productDto;
    }

notes for Pagination

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.