Design: Domain Tree
Or, “Why you should replace your entire custom-written object-oriented domain model with the WPF Visual Tree”
In his book Domain Driven Design, author Eric Evans discusses a number of ideas that should be used in domain modelling. Chief among these are three important concepts, which I’ll summarize here, though if you haven’t read Eric’s book I’d highly recommend it.
1. The separation between Entities and Value objects
Entities are objects that have real-world identities that need to be respected, no matter what the properties of the object are. As an example, if I change my name to Simon, I’m still me, even though the properties that I am made up of have changed.
Value objects, on the other hand, simply rely on the values of their properties to identify them. An example might be a TimesheetEntry - if two instances of a TimesheetEntry have the same Customer, Time, Date, Hours and Comments, it’s probably the same real-world object, and so the two are interchangeable.
When you make this separation, you can reap a number of rewards. For example, when you recognize that Value objects are dependent on the values of their properties, you can take the next step of making them immutable. Why make them immutable? Because you can then introduce object pooling, using something like the flyweight pattern, which can greatly reduce memory consumption. You can’t do this to objects that have real-world identities.
Note that the difference between an entity and a value object is not the same as the difference between a reference type (in C#, a class) and a value type (a struct). They’re real-world concepts based on our understanding of the problem domain, rather than a decision as to how they’ll be passed around in memory. Indeed, an Entity could be a struct, and a Value object might in fact be a class; that’s something for a developer to decide when implementing them, rather than an architect.
2. The separation of Stateful objects from Services
Stateful objects (either Entities or Value objects) should have only one responsibility - the responsibility of maintaining their own state. To illustrate, an Invoice (Entity) shouldn’t be responsible for generating itself, or saving itself to a database, or retrieving itself from a web service. It should simply maintain its own properties.
Services, on the other hand, have the responsibility of “doing stuff”. Usually they rely on Stateful objects to maintain business data, and don’t have any state of their own. However, some services will perform some state maintenance, but this is usually limited to “service state”. As an example, a DownloadService might remember how much it has downloaded so far, or when it was last executed, but not the monthly credit card total - that’s business data and is maintained by a proper stateful object.
3. The idea of object Aggregates
In many cases, a real-world object might be represented by multiple software objects. An example of this might be a Timesheet, which specifies a customer, consultant and project, and a list of the times the consultant worked that week, and a TimesheetEntry, which represents a single day within that Timesheet.
When such a real-world relationship exists, often the things we want to do with that object are representative of this relationship. The prime example of this is locking - when a user locks a Timesheet to modify it, in reality they want to lock the Timesheet as well as the TimesheetEntries.
Why the Domain Tree?
While some of these concepts, especially aggregates, sound great in theory, in practice in .NET I’ve found them very difficult to implement. There is no real support built into .NET to aid with aggregates, or locking a set of objects as a whole, so you’re really on your own here. Often you end up writing code to manually cascade property changes, such as an IsReadOnly property, which can get somewhat complex.
Side note: I think this is why DataSets and code generators/O-R mappers are so common. If the .NET/Visual Studio team spent as much time on supporting advanced domain modelling techniques as they’ve wasted on garbage like DLINQ/LINQ-to-SQL, the world might be a better place. There, I’ve said it
The WPF Visual Tree
The WPF Visual Tree is, surprisingly, a great source of inspiration when thinking about domain models. The Visual Tree is WPF’s way or organizing the hierarchy of controls that you might have on a window, in memory, before they are rendered.
As an example, the Visual Tree for Notepad might look similar to this:
- Window
- DockPanel
- Menu
- Menu Item (”File”)
- …
- Menu Item (”Edit”)
- …
- Border (content)
- TextBox
- ContextMenu
- Menu item (”Copy”)
- …
Some object instances can be referenced in the tree multiple times, such as Brushes, so that the same instance of a bright green Brush could be shared all over a window. Others, such as an instance of a TextBox, can only exist in the tree once - that’s why you can’t declare a TextBox as a resource and use it over and over.
One of the neat things provided by the Visual Tree, thanks to Dependency Properties, is the idea of property value inheritance. For example, every one of the controls in that tree above has a FontSize property - but I didn’t have to specify it for every one of them, and nor will they each be set to a default font.
By setting the FontSize of the Window, since the TextBox has no FontSize explicitly specified, its value will be “Unset” and whenever it is asked for it will walk the visual tree and return the FontSize of the first parent it encounters - the Window in this case. The DataContext property also works this way - it’s inherited all the way down the tree, until you specify otherwise. This is provided thanks to the Inherits FrameworkPropertyMetadataOptions enumeration value, specified when you create a dependency property.
The Domain Tree
We could also organize our domain model in a similar way. For an application designed for running a business, the domain tree might look like this:
- ApplicationContext
- Object Pool
- Value Object
- Value Object
- Application Services
- Service (exception reporting service)
- Service (caching service)
- Gateway (”Timesheet module“)
- EntityCollection (”Customers“)
- Entity (”Customer“)
- …
- EntityCollection (“Timesheets”)
- Entity (“Timesheet”) (aggregate)
- Value Object (“TimesheetEntry”)
- Value Object (“TimesheetEntry”)
- Entity (“Timesheet”) (aggregate)
- EntityCollection (”Customers“)
- Gateway (“Marketing module”)
- …
- Object Pool
Starting at the root of our application, we have what I’ll call the “ApplicationContext“. This would probably store, amongst other things, application instance-wide configuration settings, application-wide services, and a global object pool for immutable value objects.
At the next level we have Gateways. A gateway is an implementation of the Facade design pattern, and represents a “module” or “part” of the application, simplifying the model that it contains to the outside world. It also serves as a contextual boundary; a given module in the application will probably be made up of lots of entities and services, yet the outside world (other modules) don’t care about that - and in fact, they shouldn’t, because that would introduce tight coupling. The Gateway makes the module easy-to-use from other modules and the UI, by hiding the implementation details of the module.
My rule of thumb when it comes to gateways is that while most of the Entities and Value objects in a gateway might be exposed publicly, none of the services should be - invoking them (e.g., “Create an Invoice for ACME Corp. for July 07″) should be done through a simple API, exposed by the gateway.
Under the gateway lives our entities and aggregates, as well as any value objects, though these would really just point back to objects in the Object Pool (similar to how a WPF Brush only exists once, but is used many times).
If we had the same concept of Dependency Properties in our domain model, we would have access to a number of great features, the most useful of all would be property value inheritance. As an example, all of the Stateful objects in our tree might have an IsReadOnly property. Rather than continually writing code to go up and down the tree toggling values, objects at the leaves of the tree would inherit their values from their branches. So, locking an Aggregate entity would lock the entity as well as all of its value objects, whilst locking a Gateway would lock all of the objects inside that gateway (”freezing” a module if the application goes offline, for example).
In the same way that the WPF Render Tree can only be accessed by manipulating the Visual Tree, we could enforce a similar constraint that the Visual Tree can only be modified by manipulating the Domain Tree. By using Dependency Properties throughout our domain model, we’d get some great data binding features out of the box. In fact, we could even apply animations and styles to our domain objects - now there’s a scary thought
Is the WPF Visual Tree suitable for use as our Domain Tree?
I am not sure if it would be safe to directly swap the objects in our domain model to use Dependency Objects/Properties and some of the methods/events in the Visual Tree (for example, inheriting Visual to get the GetVisualChild() method, thus allowing us to use the VisualTreeHelper). It might impact the possibility of re-using the domain model in other platforms, such as ASP.NET, though I personally don’t like the idea of re-using a domain model anyway (it’s not often we find cases where a Web and a Windows version of the same application exists and offers exactly the same functionality - often they’ll be different, in which case you should really have a different domain model).
In any case, I introduced the idea of using the WPF Visual Tree just to serve as inspiration. I would love to see support for such a concept in the .NET Framework, that is, the concept of a domain object tree, with the ability to easily walk the tree, built-in pooling, and property value inheritance. I wonder how hard it would be to recreate all of those features?
Filed under: WPF

How hard would it be to recreate all the features? Just extract all code from the WPF assemblies using Reflector, chip away anything that doesn’t look like Domain Model code, and you should be good to go
Seriously, though: The idea of using a dependency-property-like construct for inherited property values sounds cool. I’d like to share some of the thoughts I had recently.
I worked on a WPF prototype program (a quiz program) in the recent past. I made a clear separation between business objects and UI. This naturally implies that I had to implement INotifyPropertyChanged ad nauseum. Then I thought “to make it easier to identify which property is being changed, I should probably introduce ‘PropertyName’ constants or something”. Then I thought “maybe there’s other useful information I can store too [and now it comes] sort of like Dependency Properties and their metadata”.
So I felt like being only one step away from wanting a dependency-property-like concept in my business entities. And today I read your blog post … I would love to do a bit of brainstorming about these concepts.
Dirk
[…] Stovel in his post on The Domain Tree describes the similarities between concepts listed in Domain Driven Design by Eric Evans and some […]
Brownie Points & Paul Stovell: Domain Tree
Very interesting Brownie Points Paul Stovell
[…] The Domain Tree - a more high-level look at how I think a rich client application might be designed […]