With my book project on top of my ordinary client projects, I unfortunately haven't had much time for pet projects over the last year or so. The only exception being NWorkspace.
The basic idea with NWorkspace is to create an abstraction layer on top of different persistence solutions. But it's not like an API that the persistence solutions will have to implement (because why would they care about my API
There is a whole bunch of reasons behind why I started building NWorkspace. First of all, I wanted to be able to write a single set of Repositories (in my DDD-ish projects), that could be used in tests both with and without a database. I find it a good tool for when it comes to moving the bar as to how many of the test executions must be database-bound, and at the same time it's a dumb-code-reducer.
I was also thinking about the increased possibility of building tools on top of a standardized API, that would then work with several different persistence solutions. I have for example myself built domain specific type-safe queries on top of NWorkspace.
Another reason was to be able to show live demos and let the users interact with the applications in production-like ways early on in the projects, without having to build and install the database. That way you will be extremely flexible when it comes to making large model changes. Still, when you decide that it's time to swap to a real persistence solution, everything you have done so far regarding querying, for example, should still be valid. Sure, you might need to optimize some things here and there, but that's perfectly alright.
Yet another reason was to simplify the API for the consumers to the persistence solution, since a simplification is quite often just what is needed. Take transactions, for instance. How often do you execute three updates one after another without a transaction? Not that often, right? (When you need the full power, it's always there of course, if you just bypass the abstraction layer.) Another typical example is connection management; NWorkspace takes care of that with a decent default approach so that you don't need to build it yourself.
To give you an idea of how the API can be used, here's an extremely basic snippet (without specific DDD-concepts). First we instantiate a workspace, and in this example we are using NHibernate.
private IWorkspace _ws = NHibernateWorkspace(_sessionFactory());
Then we'd like to create a new customer and flush all changes known to the Unit of Work to the database:
Customer c = new Customer();
c.Name = "Saab";
Then fetch that customer (which in this case will be found in the Identity Map):
Customer c2 = _ws.GetById(typeof(Customer), c.Id);
And finally, fetch a list of all customers and then empty the Identity Map.
IList customers = _ws.GetByQuery(new Query(typeof(Customer)));
Current state and future plans
I currently have one adapter implementation for NHibernate, and another one for an extremely simple in-memory based solution of mine. This is basically a couple of sets of Hashtables that can be serialized to disk at termination and de-serialized at startup.
I've been playing with NWorkspace on and off since December last year and I have recently used it on a big project that has gone live. Still, the current version of NWorkspace isn't anything I'd like others to use, since there are plenty of simplifications and rough edges.
Nevertheless I still like the idea very much. Sure, there are pros and cons, but I so far still consider it an interesting and often useful approach. It's a time saver and helps reduce infrastructure code, and since it also works well in production, it might be interesting for others as well, right?
The idea is to find some time to clean up the current bits enough so I can publish them (without having to wear sunglasses and a scarf over my face when going to the local supermarket), and then see if someone wants to come along and set up a project for creating a version 1.
If/when something happens with NWorkspace, you'll see it announced first here: www.jnsk.se/weblog/