in my ASP.NET MVC application I have a service that had a method for paging, sorting and filtering of Vehicle Makes:
public class VehicleService : IVehicleService { private readonly DbContext _context; public VehicleService(DbContext context) { _context = context; } public async Task<IPagedList<VehicleMake>> GetVehicleMakesWithPaginationAsync(string search, int? page, string sort) { var makes = _context.VehicleMakes.AsQueryable(); switch (sort) { case "Name desc": makes = makes.OrderByDescending(x => x.Name); break; default: makes = makes.OrderBy(x => x.Name); break; } return await makes.Where(x => x.Name.StartsWith(search) || search == null).ToPagedListAsync(page ?? 1, 5); } }
After the review of my code, I was told that sorting, filtering and paging should be in separate classes that have interfaces. I implemented that in following way:
Sorting:
internal class Sorting : ISorting { private readonly DbContext _context; public Sorting(DbContext context) { _context = context; } public IEnumerable<VehicleMake> SortMakes(string sort) { var makes = _context.VehicleMakes.AsQueryable(); makes = sort == "Name desc" ? makes.OrderByDescending(x => x.Name) : makes.OrderBy(x => x.Name); return makes; } }
Paging:
class Paging : IPaging { private readonly ISorting _sorting; public Paging(DbContext context) { _sorting = new Sorting(context); } public async Task<IPagedList<VehicleMake>> GetPagedListOfSortedMakes(string search, int? page, string sort) { var sortedMakes = _sorting.SortMakes(sort).AsQueryable(); return await sortedMakes.Where(x => x.Name.StartsWith(search) || search == null).ToPagedListAsync(page ?? 1, 5); } }
And then in my service:
public class VehicleMakeService : IVehicleMakeService { private readonly DbContext _context; private readonly IPaging _paging; public VehicleMakeService(DbContext context) { _context = context; _paging = new Paging(context); } public async Task<IPagedList<VehicleMake>> GetVehicleMakesWithPaginationAsync(string search, int? page, string sort) { return await _paging.GetPagedListOfSortedMakes(search, page, sort); } }
This works well, but I’m not sure if I implemented this correctly. Is there a better (cleaner) way to do this?