Separating paging, sorting and filtering 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&lt;IPagedList&lt;VehicleMake&gt;&gt; GetVehicleMakesWithPaginationAsync(string search, int? page, string sort)
    {
        var makes = _context.VehicleMakes.AsQueryable();

        switch (sort)
        {
            case "Name desc":
                makes = makes.OrderByDescending(x =&gt; x.Name);
                break;
            default:
                makes = makes.OrderBy(x =&gt; x.Name);
                break;
        }

        return await makes.Where(x =&gt; x.Name.StartsWith(search) || search == null).ToPagedListAsync(page ?? 1, 5);
    }
}


VehicleService interface:

public interface IVehicleService{
Task&lt;X.PagedList.IPagedList&lt;VehicleMake&gt;&gt; GetVehicleMakesWithPaginationAsync(string search, int? page, string sort);
}


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&lt;VehicleMake&gt; SortMakes(string sort)
    {
        var makes = _context.VehicleMakes.AsQueryable();

        makes = sort == "Name desc" ? makes.OrderByDescending(x =&gt; x.Name) : makes.OrderBy(x =&gt; x.Name);
        return makes;
    }
}


Sorting interface:

interface ISorting
{
 IEnumerable&lt;VehicleMake&gt; SortMakes(string sort);
}


Paging:

class Paging : IPaging
{
    private readonly ISorting _sorting;

    public Paging(DbContext context)
    {
        _sorting = new Sorting(context);
    }

    public async Task&lt;IPagedList&lt;VehicleMake&gt;&gt; GetPagedListOfSortedMakes(string search, int? page, string sort)
    {
        var sortedMakes = _sorting.SortMakes(sort).AsQueryable();
        return await sortedMakes.Where(x =&gt; x.Name.StartsWith(search) || search == null).ToPagedListAsync(page ?? 1, 5);
    }
}


Paging interface:

interface IPaging
   {
    Task&lt;IPagedList&lt;VehicleMake&gt;&gt; GetPagedListOfSortedMakes(string search, int? page, string sort);
   }


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&lt;IPagedList&lt;VehicleMake&gt;&gt; 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?
For my money it would only be worthwhile having separate classes for Sorting/Filtering/Pagination if they were generic and able to work on multiple entity types. Even then they'd more likely be helper classes than a part of the top-level application interface.

If the current requirement of your application is purely to do what GetVehicleMakesWithPaginationAsync does then the proposed split into 3 classes doesn't strike me as justified. I'm more concerned about the nature/names of the parameters being passed. 

Why not make "sort" a boolean flag called "sortDescending"? And I'd rename search to namePrefix or something that makes it clearer. 

Lastly - is the AsQueryable() really needed?