简体   繁体   中英

Specification pattern with Entity Framework generic repository

Recently I have encountered an article Implement the Query Specification pattern and I am confused about using specification pattern with generic repository.

I have already a generic repo like this:

public interface IGenericRepository<T> where T:class
{ 
    IReadOnlyList<T> GetAllAsunc(int id); 
    IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter); 
    T GetById(int id)
    void Add(T item); 
    void Update(T item); 
    void Delete(T item); 
}

And a sample method for specification pattern

public BaseSpecification(Expression<Func<T, bool>> criteria)
{
    Criteria = criteria;
}

I can send any expression with IReadOnlyList<T> FindAsync(Expression<Func<T, bool>> filter);method. So, I don't really understand why I need specification pattern with generic repository. It looks they are doing same things. Could you clarify this?

The specification pattern covers more than just a filter expression, it also covers eager loading and pagination. In your example, if you were dealing with an entity that referenced 3 other entities and had a child collection, how would you tell your repository method which of those should be eager loaded? If your List method could return hundreds of thousands of rows, how would you tell it to load just a page of 50 at a time?

In my personal opinion, using the Specification is a SRP band-aid on a generic repository. Generic repositories are an anti-pattern in EF systems where you are positioning your repository code to have a great number of "forces" lobbying for change using the Specification to mitigate that. I would never advocate for trying to build an MVC web application with a single generic Controller<T> implementation, and for the same reason I don't advocate using Repository<T> . Specifications do not protect callers from being polluted with domain / EF knowledge because every expression passed in must conform to the rules set out by the domain implementation. While a specification might handle filtering, eager loading, and pagination... What about sorting, projection, or other aggregate functions like exist checks and counts? At the end of the day it's a complexity rabbit hole trying to satisfy SOLID principles making your code considerably more complex and harder to follow, and slamming head-first into barriers repeatedly as new requirements don't conform to past assumptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM