This is with respect to my solution of implementing Paging & Sorting in Domain Driven Design with intention of not to pollute the Domain models and repository contracts,
Base class for REST Request
public class AbstractQueryRequest {
...
private int startIndex;
private int offset;
...
}
Interceptor to retrieve the Query Meta data and store it in ThreadLocal container
public class QueryInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
...
QueryMetaData.instance().setPageMetaData(/*Create and set the pageable*/);
}
}
Container for Query Meta data
public class QueryMetaData {
private static final ThreadLocal<QueryMetaData> instance = new ThreadLocal<>() {
protected QueryMetaData initialValue() {
return new QueryMetaData();
}
};
public static QueryMetaData instance() {
return instance.get();
}
private ThreadLocal<Pageable> pageMetadata = new ThreadLocal<>();
public void setPageMetaData(Pageable pageable) {
pageMetadata.set(pageable);
}
public Pageable getPageMetaData() {
return pageMetadata.get();
}
//clear threadlocal
}
I intend to retrieve this ThreadLocal value in the repository, if available use it with the queries to the datastore.
I hope this may not be a very dirty solution, but want to know is there better widely used pattern for this.
don't use your solution. It's quite complex and will be hard to debug and maintain. If you start using async methods it won't even work.
I don't understand why you can't have sorting/paging properties in your repository methods? If you want a cleaner solution you might create a new object which carries the sort and paging settings.
When you want to fetch data you typically do it through your application services. And those can use your repositories directly before converting the result to DTOs.
then you got something like:
public class YourAppService
{
public YourAppService(ISomeRepository repos)
{
}
public IList<UserDto> ListUsers(string sortColumn = "", bool ascending = true, int pageNumber = 1, pageSize = 30)
{
var querySettings = new QuerySettings(sortcolumn, ascending, pageNumber, pageSize);
var users = _repos.FindAll(querySettings);
return ConvertToDto(users);
}
}
you can read more about sorting and paging in my article here: http://blog.gauffin.org/2013/01/11/repository-pattern-done-right/