Domain Driven on Naked CLR?
Again, a story from class. We are currently building a sample app together, and I get to see just how painful it is to try to build domain driven applications on the naked CLR.
A lot of the stuff that makes DDD possible (rich object graphs, for instance) is entirely too hard to do without tool support. The end result is a transaction script pattern, where there is a chain of method calls that ends up with a call to the DB, usually to a stored procedure. I thought about keeping the SQL in the application layer, but to do it correctly, I would need a real data layer, and that basically means that I crack opens Fowler's Patterns Of Enterprise Applications and start implementing Unit Of Work and Identity Map, etc. Horrendous amount of work, frankly.
Assuming that you have no access to tooling, and you don't have the resources to built NHibernate-sque framework, how would you approach building a Domain Driven application on the naked CLR?
Is it even possible?
Comments
Oren,
You might be overcomplicating the issue. If naked CLR was all you had (shudder), you could go for Fowler's Table Module design and wrap domain classes around DataRow's ala NEO. It's definitely a compromise, but you get the DataSet change tracking for Unit of Work while stll getting something that looks like a Domain Model class.
Jeremy
Domain Driven != SQL Driven.
There are lots of instances (pun intended) where you certainly don't need nor desire a relational backend.
For those cases you can either use a OODB such as db4o or if you can afford to keep all domain objects into memory something like Bamboo.Prevalence.
Rodrigo,
While I agree with you in principal, the situation that I am talking about is truly naked CLR.
I am teaching a bunch of students about .NET, and I don't want to introduce any new tools into the equation.
I do want to use good design, though
Oren,
Good for you, this is an excellent exercise! Are you teaching them in an Agile context? Keep up the blogging about the class, love it.
I am still doing DD on the naked CLR, it does have it's pain points, but also has advantages as well. This may sound crazy, but it is an approach that works, similar to Hibernate mapping, only the mapping is actually a class library. This is done for type saftey and also helps define relations, it also gives you intellisense against the model mapping.
If the backend is a DB a single static class can use the maps to generate complex queries, joins, and even better the relational mapping can be changed without the class changing.
I also define a completely type safe query class used to load objects, this will eventually be replaced with LINQ and is actually the most complex part of this approach.
EntityLists are mapping aware so when a list changes the relations are tracked and updated, the list only knows a relation exist, the type of relation is not it's concern.
Entities use the mapping classes to fire change events, and track changes. Then the persistence layer can persist the data based on the mapping.
This approach is very similar to NHibernate in the fact that the Domain Objects are almost poco and can be left untouched if the underlying schema/relations change. Just imagine that the mapping files are classes instead of an xml file or attributes.
I like this naked CLR approach, it's not much extra work, I can create multiple versions of Domain Object using the same mapping, span mutiple tables, do lazy and aggressive loading, eaily create read-only Domain Objects and Collections.
I'm assuming that you are talking about the aggregates in DDD, DDD is so much more then the persitence of the Aggregates.
But yes, If you got complex aggregates, the persitance of thoose aggregates will be complex. I've built a few apps with DDD on the naked CLR but that has been with fairly simple aggregates and a very simple implmentation of IM, but most of the times I fire up either NHibernate or NPersist do to the persistance for me.
The thing is that being true to DDD, you should not really care about the persitance of the aggregate. Your focus should be on the domain and the bussinessproblem at hand. So if you go for DDD you should also go for ORM. If you feel that ORM is to complex for your solution / team, then DDD is probably not for you and there is a lot of other (not as good in my opinion though ;) approaches to model your bussiness logic. Maybe based on a table module.
Well - it isn;t at all hard to write a clean domain design without NHiberante or similar.
The code that LLBLGen v1 generated was pretty simple DAO stuff - would take 30 mins to write a basic datalayer that way.
Oh, right. Naked CLR. Much better then!
I would go through the native persistence mechanism of the CLR: System.Runtime.Serialization.
You might want to go through designing a persistent desktop application with support for undo (persistent undo) and suddenly you'll see yourself talking about the command design pattern. Sooner than you'd think the students will be rediscovering prevayler and the joy of OO ;)
I did that for 4 hour mono/boo/prevalence course and it worked.
Patrik,
In true DDD you don't care about persistance, this is until you need to persist.
In DDD your concern is the domain, however 99% of the time your going to have to persist the domain and these days it's going to be a database. Therfore you decouple the domain from the persistance as much as possible.
I like the fact that Oren has chosen not fire up NHibernate and persist with the naked CLR, can't wait to see where this goes.
Casey,
LLBLGen 1.0 is the SP mapper, right?
There are a lot of limitations to DDD with SP, in my point of view. Rich domain model is particularly hard.
Casey,
LLBGEn 1.0 was a mapper that had it's basis in SP's. Eg Bottom-Up. Where the database stipulates how the domain will look. That is contradictionary to what DDD is where Tables in the database are prehibited of stipulating how the domain is supposed to look like. DDD is middel out.
Mike,
I'm not saying that persitance isn't important. I'm just stating that in DDD persitances is a separate thing. Separate in that for the bussiness problem at hand it is not important and not somthing that domain experts focus on or care about. Given that, the aggregates should be able to be what they are and not constrain themselfes based up on the persitance choices. Therefor a capable ORM like NH or NP is to prefer since they are target at persisting object models and you can focus on the design of the aggregates.
Oren,
The problem with DDD and SP's is the flat view of the world that SP's often enforces. There are cases where it is possible, but I totally agree that it will be a challange to build a DDD based system with sprocs as persistance layer. But the real objection I have against SPs/DDD is what I wrote above. People who write their sprocs first and then their model has a data-centric view of the world. That will clahs with DDD
To answer Oren's original question, I think the answer is "you reallly do write all that code." From what I can tell, this is the approach that CSLA takes. Sure CSLA has some helper classes, so it isn't naked CLR, but you still have to write every bit of each layer. CSLA doesn't really help you.
Awesome exercise. I typically an overwhelmed when looking at such amounts of work, and I throw my hands in the air, say "never mind", and I wait until I can use good tools.
Patrik,
I completely agree. Could you define aggregates in this context?
Oren,
Please roll your own, just once, please, and do something more complex.
Comment preview