It's possible to write repository which have default CRUD operations. For example:
public interface IRepository<TEntity>
{
TEntity FindByIdentity(object identity);
TEntity FindBy(Expression<Func<TEntity, bool>> specification);
IList<TEntity> FindAll();
IList<TEntity> FindAllBy(Expression<Func<TEntity, bool>> specification);
TEntity Save(TEntity saveable);
void Delete(TEntity deletable);
}
Expression> is basically Specification and queries can be encapsulate that way. If we have that kind of Repository then we don't need to write many specific repositories.
Alternative path is create Query object. We could add interface of that query to Core/Busines Logic layer and implementation to Services/Data layer. That way we have nicely named queries like AllPreferredCustomersQuery. It's quite similar to specifications, but specifications don't use infrastructure and therefore we may add it to Core/Business Logic layer. Query objects are more configurable (e.g. possible to add limits, fetching strategies, joins etc.)