Pregunta

In Domain Driven Design, should the specification pattern for paging/pagination exist on the Repository level or Application level, or another layer? Trying to see what Eric Evans author of DDD stated. Then I can implement the code in correct layer. Sample code below.

Paging meaning, example have 100 products, and want to display 5 for each 20 pages.

Example 1: https://deviq.com/specification-pattern/

// https://github.com/dotnet-architecture/eShopOnWeb
public IEnumerable<T> List(ISpecification<T> spec)
{
    // fetch a Queryable that includes all expression-based includes
    var queryableResultWithIncludes = spec.Includes
        .Aggregate(_dbContext.Set<T>().AsQueryable(),
            (current, include) => current.Include(include));

    // modify the IQueryable to include any string-based include statements
    var secondaryResult = spec.IncludeStrings
        .Aggregate(queryableResultWithIncludes,
            (current, include) => current.Include(include));

    // return the result of the query using the specification's criteria expression
    return secondaryResult
                    .Where(spec.Criteria)
                    .AsEnumerable();
}

Example 2: https://thinkbeforecoding.com/post/2009/01/19/Repositories-and-IQueryable-the-paging-case

public interface IPaged<T> : IEnumerable<T>
    {
        int Count { get;} 
        IEnumerable<T> GetRange(int index, int count);
    }

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> GetRange(int index, int count)
        {
            return source.Skip(index).Take(count);
        }

    }

Code for Paging/Pagination

¿Fue útil?

Solución

Paging is an implementation detail.

DDD concerns itself mostly with architectural design; it doesn't have much to say about how you handle page breaks, since handling concerns like paper size or screen length is not part of the business domain, although it can be a part of the design process.

Where should you put your paging? Where it is most convenient for you.

I see a lot of articles talk about putting this responsibility in the repository, using either a Specification Pattern or some other way to filter records. That's fine, if you want to work that way. Personally, I see paging as a display concern, so I would expect to see it closer to the UI or printing operation than that, perhaps in the ViewModel or Service Layer.

Letting the repository handle the paging has its benefits. If you design it correctly, you can potentially reduce the amount of data you are retrieving, since the paging mechanism will only retrieve the data that it needs for each page, and will not retrieve data for pages that are never printed or displayed.

Licenciado bajo: CC-BY-SA con atribución
scroll top