You use the repository to list the aggregate root. Quite often, your controllers work with an aggregated root, which you can filter, sort, etc. As needed.
Therefore, I use the repository in accordance with what has already been mentioned.
However, sometimes I have to work in more complex specifications, where using the aggregate root and / or a whole group of repositories is either painful, inefficient, or simply impossible. For example, you may need to run a large business report, or perhaps run a batch command.
In such cases, I also defined ICommand
/ IQuery
, with the NH base, to take care of the plumbing material (as the general Repository
does).
What I then do is make an interface that represents a contract for specification, exposing any elements that I may need to help me build the necessary parameters. Then I do the implementation of this specification, using NH as the basis, executing the specification, using any method that is most suitable (HQL statement, raw SQL, criteria, QueryOver ... whatever).
Here is a rough illustration of what I mean. Please note that I use an arbitrary ICommandProvider
, which is some object that creates new instances of the command as needed (in case you need to issue several commands in one operation). I would register my teams using IoC and ask the provider to work with him to create instances of the teams.
public interface ICommand { } public interface ICommandProvider { TCommand Create<TCommand>() where TCommand : ICommand; } public interface IQuery<TResult> : ICommand { TResult Execute(); } public class NhCommand : ICommand {
Use in the controller might be something like this:
public class DelinquentAccountsController : Controller { protected ICommandProvider CommandProvider { get; private set; } public DelinquentAccountsController(ICommandProvider commandProvider) { CommandProvider = commandProvider; } public ActionResult Index(decimal amount) { var query = CommandProvider.Create<IDelinquentAccountsQuery>(); query.AmountGreaterThan(amount); return View(query.Execute()); } }
Nothing is said that you cannot perform all data access with a command / query, but this works more than I need. I believe that the standard repository method (using LINQ against NHibernate) handles 95% or so access to the data that my applications require.