NWorkspace and DDD

Tap, tap... Anyone there?
;-)

Today I'd like to show you how I use NWorkspace in a DDD-inspired design. Here I have a repository for each aggregate, therefore, there's a repository called CustomerRepository, for example.

The CustomerRepository will get an IWorkspaceForRepositories in the constructor. This interface is just like IWorkspace, except that it doesn't contain PersistAll() or Clean(). The idea is that the consumer (such as an Application layer or even the presentation layer directly) will coordinate the complete session and consequently doesn't want the repositories to interfere. Therefore, PersistAll() and Clean() will be done by the consumer (via the IWorkspace).

OK, let's repeat part of what I have shown in previous blogposts here and here, but this time with repositories involved. The changes are marked in bold.

//--Instantiation of workspace.
private IWorkspace _ws = new WorkspaceNH(_sessionFactory);
//Here the repository gets the _ws as an IWorkspaceForRepositories.
private CustomerRepository _r = new CustomerRepository(_ws);


//--Insert of an instance.
Customer c = new Customer();
//...Do stuff with Customer...
_r.Add(c);
_ws.PersistAll();


//--Reconstitution of an instance.
Customer c = _r.GetOrderById(42);
//instead of this:
//Customer c = (Customer)_ws.GetById(typeof(Customer), 42);


//--Querying...
IList aCustomerList = _r.GetOrdersByName(“Volvo”);
//instead of this:
//NWorkspace.IQuery q = new Query(typeof(Customer));
//q.AddCriterion(new Criterion("Name", Operator.Equal, "Volvo"));
//IList aCustomerList = _ws.GetByQuery(q);

//... or set up query and call:
IList aCustomerList = _r.GetOrdersByQuery(q);

//... and if it's a typesafe list, that's "hidden" by the repository, for example, like this:
CustomerList aCustomerList = _r.GetOrdersByQuery(q);
//instead of this:
//CustomerList aCustomerList = new CustomerList();
//_ws.GetByQuery(q, aCustomerList);

It's important to note that I still think that the Unit of Work and Identity Map should typically "span" several repositories and therefore be controlled by the consumer instead of by the repositories.

To summarize the differences when using DDD (on a micro level like the API above), the querying becomes very simple. You can decide yourself whether you want the repositories to use the querying API for defining the queries or whether you want the consumer to define the queries and just ask the repositories to execute them (depending upon the situation). That's more or less it. The most interesting things with DDD are more on a macro level, but this a completely different topic. Here I just wanted to show how you *can* integrate NWorkspace with a DDD-ish design.

Comments?