There has been some discussion over the topic already and there are different opinions. I have been using Repository model all the way so far. I have implemented generic base repository for all common operations and when there are some specific needs (view specific query for example!) for some types then I’ll create specific repository. I know that repositories should be created only for aggregate roots but there I have encountered a little problem. View needs to display data from different entities (aggregates or not) so I cannot always follow the principle of repository per aggregate root. So this poses a problem here – repositories are cluttered with view specific needs. And moreover – repository methods are decorated with sorting and paging parameters which definitely shouldn’t be there. So I decided to change that.
There have been some discussion about using multiple models of the domain for different purposes. For example different kind of a model for reporting purposes. It can even be different kind of data store for that model. Udi and Ayende (didn’t find exact posts anymore) have blogged about that before. Complex views with special needs can be also considered as a way of reporting. In my case, using wholly different model for a view is kind of a overkill so I try to leverage the problem by using query objects separated from the repository. They don’t use repositories by themselves so query objects can be viewed as "specific repositories for views" and they live only in presentation layer. And they don’t operate with domain objects, only with view specific objects like DTOs, filtering specifications. By using this kind of approach, writing complex view specific queries should be pretty easy. I’m not tied to NHibernate criteria, I can use HQL or even ADO.NET. Currently I’m using HQL which returns directly DTOs but I’m thinking of giving a try to LINQ for NHibernate.
When using repositories, I used Expressions to represent sorting and filtering specification. But this seems now overly complex when considering that there were some heavy mappings from string format to Expression format. So now, when it’s only a presentation concern, I can use plain strings, just like they come from the view and do the proper mappings in the query object itself. Like they say – KISS.