One Domain-Driven-Design solution to the problem of where to place querying, sorting, and paging logic is to use a Specification. The Specification design pattern describes a query in an object. So to encapsulate a paged query that searches for some products, one might create a PagedProduct specification which would take in any necessary parameters (pageSize, pageNumber, filter). Then one of your repository methods (usually a List() overload) would accept an ISpecification and would be able to produce the expected result given the specification. There are several benefits to this approach. The specification has a name (as opposed to just a bunch of LINQ expressions) that you can reason about and discuss. It can be unit tested in isolation to ensure correctness. And it can easily be reused if you need the same behavior (say on an MVC View action and a Web API action, as well as in various services). Further, a specification can also be used to describe the shape of the data to be returned, so that queries can return just the data they required. This eliminates the need for lazy loading in web applications (bad idea) and helps keep repository implementations from becoming cluttered with these details.

Generic Specification Interface

Generic Specification Implementation (Base Class)

A Simple Specification

The following specification will load a single basket entity given either the basket’s ID or the ID of the buyer to whom the basket belongs. It will eager load the basket’s Items collection.

Generic EF Repository with Specification

Below is an example repository method that uses a specification to filter and eager load data related to a given generic entity type, T.

Although it’s not recommended to return IQueryable from a repository, it’s perfectly fine to use them within the repository to build up a set of results. You can see this approach used in the List method above, which uses intermediate IQueryable expressions to build up the query’s list of includes before executing the query with the specification’s criteria on the last line.

Resources

Design Patterns Library (includes a module on Specification)
Repository Pattern

Comments are closed.