
I was reading through my RSS feeds and email, just having returned from Paris and I was asked to take a look at a project from Microsoft Spain up on Codeplex.
In reading the summary, it looks to be a sample application utilizing some high-end tricks from DDD (emphasis mine):
This project is a sample implementation of most used patterns in Domain Oriented Architectures based on simple scenarios easy to understand (Customers, Orders, Bank Transfers, etc.).It is an Educational example, not a real world system … useful from a patterns implementation point of view, but not necessarily as a whole business application.
You might think I’m gearing up for a rant :). But I’m not - it’s nice to see someone from Microsoft take on these concepts and offer a sample.
So, while not ranting, I think it might be good to take a measured look at this effort and see if we can ask some intelligent questions - in the hopes of maybe helping out the author.
Also - I did see Ayende’s posts (they came next in the RSS feed). I’m sure he’ll have more concrete things to say. I’ll keep my opinions a bit more contextual.
Here’s the thing: DDD isn’t a set of patterns that lend themselves to a “sample app”. I had to deal with this when discussing it for the MVC Storefront. It’s a mindset, a process, and a commitment to your client to write nimble, business-oriented code.
The client-communication aspect of DDD (Ubiquitous Dialog) is probably the biggest deal (from my limited perspective) - it bends your mind as a developer to understand your client, and it pushes your client to understand you and your processes.
Given that understanding - creating “DDD samples” is a bit of a catch-22. Who’s the client? What’s the business process? How/Where/When did you make the architectural decisions?
Finally - as Ayende points out - if it’s simple you don’t really need DDD. But banking? Simple? If you find yourself writing a sentence with the words “banking, simple, not real-world” you might want to rethinking what it is you’re doing.
To be sort of direct about it: it’s an invalid sample of solving a problem that doesn’t exist.
But! As I mention - let’s be concrete, constructive, and peer under the covers.
There’s a lot of abstraction in this application. I don’t like heaps of abstraction, but sometimes in a simple, non-real-world sample app of a simple scenario that’s actually incredibly complex - you need it.

In looking at this overall structure - the first thing that I’m questioning is the abstraction of the patterning. Isn’t that supposed to be the other way around?
In other words - if you find yourself writing an interface for the State Pattern (IStatePattern ?) - it might be worth it to ask yourself just what it is you’re trying to do.
Patterns are exactly that - a way to implement code. Interfaces describe a contract in your API. If your API describes software patterning then I spose it’s OK - but generally patterns belong in code, not as objects.
Abstracting patterns and implementation details seems a bit off to me. Things like “ValueObject” and “ISQL” seem a bit like drawing your footsteps on the ground in the forest before going for a hike:

Thought Number 1: These are developer concepts - not business concepts. They don’t belong in the domain.
It might be nice to see how a problem is solved actually *using* the UnitOfWork rather than explicitly declaring a UnitOfWork object. Same with SQL, Entity, ValueObject, etc.
Speaking of UnitOfWork - here’s the implementation of IRepository:

First - a nitpick: using the Repository does *not* ensure persistence-ignorance. You can use any type of abstraction you like - including ActiveRecord. This sentence is a tad misleading.
You can see there’s in IUnitOfWork that’s being used right inside the Repository. For those who don’t know what “UnitOfWork” is - well it’s a way of transactionally flushing changes to a persistence store (aka Database). You might pull 5 objects out of a database, update 2, and delete 1. Maybe even add one more. The UnitOfWork pattern, when implemented (in EF’s DataContext or NHibernate’s Session object) handles this nicely for you.
This is spiffy - but it has nothing to do with the Repository pattern - in fact it’s confusing the concepts to mix the two. The Repository Pattern is all about encapsulating calls to your DB as methods to do a thing. These calls are (typically) atomic.
UnitOfWork, on the other hand, manages objects and stores their state. You can make the two work together in the same way you can walk on your hands - but it tends to get uncomfortable really quickly.
For instance: the scope of a UnitOfWork for a web application is the lifetime of the request. This makes sense. You open up a single UnitOfWork (NHibernate calls this a session) - you ask it for data, you might update some stuff too - and it flushes the changes when the request ends.
How does this work with a Repository? The answer is: it doesn’t. Each operation on a Repository, in theory, is supposed to be atomic - so I decided to snoop and see how the author deals with this.
The great news is that I found some tests (kisses and hugs for that! Tests aren’t only for the geek writing the code - they’re also for people reviewing it!). This one is dealing with adding France to the database:

Reading a suite of tests is a great way to see what the developer is trying to do with the application. It also shines a light on why writing clear, concise tests really matters (for when reviewers read your code).
The first thing you ask yourself when reading this test: what is the author trying to say? What are they trying to do with this codebase? It’s the same as if you’re writing an essay in college.
From what I can tell - this test is supposed to test if the Repository can add a new item (Country). But if you read it - is that’s what is happening? No - the UnitOfWork is actually the thing under test here - it’s the one handling the object.
It might seem like a nit-pick, but this little detail is a classic indicator of over-engineering. If you find that you can’t test a thing because 5 other things get in the way, you’ve thought about it too much.
The next problem: I have no idea where the Repository is coming from. It’s not being injected - instead it’s being pulled from an IoC container. Inversion of Control is all about a process instantiating an object for you, rather than explicitly creating it in code.
This call to the container in the first line (to get the ICountryRepository) is inverting inversion of control and it’s weird. Best to be explicit here and use a Mock or a Fake of some kind. I don’t know what’s in the Container - which is not supposed to be the case for testing.
Next - I see what I came for: “countryRepository.UnitOfWork.Commit()”. And I’m wondering: if I’m using IoC and UnitOfWork - why do I need this Repository?
Moreover - why doesn’t Add() commit the country to the database? That *is* the name of the method - so what are we “Add()ing” the country to? The answer to this question is that we’re adding it to the UnitOfWork object tracking behind the scenes. Add() can’t send the record to the database as it would commit all the changes explicitly - which defeats the whole point of UnitOfWork.
So - do we need this Repository? Or any Repository with this setup? No - we don’t. This sample app doesn’t either and it’s not clear why it’s in there.
What would be a better setup is to inject the UnitOfWork as a Context or a Session - like NHibernate or EF does. Abstract that if you like - add objects to it and off you go (I have some code if the MS Spain guys would like it).
One of the things with DDD as I mention initially is that you model your domain tightly after your client’s business - writing code that follows as closely as it can to the real world.
Often, when you nail down a really good dialog between yourself and a person at your client’s business (called the domain expert) - you find that you can ask them specific questions about a coding problem, and you can resolve the problem quickly based on this dialog.
To see how this might work - consider the creation of a BankAccount. Your client is Bank of the World and you need to create a really simple sample app (that’s also incredibly complex) and you’re building out the part where an account gets created.
How do you do this? If you put on your Geek Hat, you could probably figure something out. The idea with DDD, however, is that you ask your client: “hey - what’s the process for creating a bank account?”
They will likely respond with “the AccountsSupervisor has a desk at the bank where a client will come in, fill out a form, and we would run some checks using our SuperWhammadyneProcessor (credit scores, bank service records, etc). We would also see if they’re an existing customer - and then we might try to upsell them a credit card”.
From this, we have a clearer understanding of the things we might create: AccountSupervisor, NewAccountApplication, SuperWhammadyneProcessor, AccountUpsells - something like that.
I wanted to see what this sample app was doing - so I took a look here in the BankAccountFactory:

I’m already feeling a bit uncertain about this approach - and taking a look at the code:

There’s a few things that jump out at me. The first is that you have to pass in the bankAccountNumber - and it’s not clear why. This is clearly a process decision - but as a reviewer of the code I’m wondering how the account number can be created without the account being created first?
Next - does the account really unlock itself? And then set its own customer? I think this is backwards - accounts belong to Customers in a typical banking scenario.
The next question is “why the Factory Pattern” here? Why at all? If we were really doing DDD - this would be answered by “it’s how the client does it” - but I have a feeling they don’t have a little plastic factory creating accounts (or maybe they do?).
This is where the whole “Domain-Focus” of this sample application falls to pieces for me. There *are* justifications for using a Factory like this - but without the client context this is meaningless to me - which makes this DDD sample application meaningless.
What might be a better approach is to try to spin in at least a smidgeon of fake dialog - or some type of story so I can say “ah HA! They do have a little plastic account factory!”.
But there’s no problem being solved here - just a lot of code.
It’s nice to Microsoft trying to help out developers who have questions about these concepts. But sometimes a demo app - even if you say it’s a demo app and not real world - does nothing but confuse people more.
I get asked about patterns about 5-7 times a week. Things like “when should I use X?” or “what do you think about the Repository?”. I’m asked these questions mainly because the .NET community tends to be pretty confused on the topic of implementing a real application “properly”.
With meaningless examples like this - I can see why.
My name is Rob Conery and I am the owner/smooth operator of Tekpub, creator of
This Developer's Life, and an avid Ruby/Rails/.NET developer.