In my last post, I talked about a Generic Expression Builder class for easily creating domain entities through expression builders. This generic base class takes away some of the burden while developing these expression builder classes. Expression builders are generally useful inside the domain when you need to create and set up a complete aggregate root from scratch, not to say that expression builders aren't useful in other parts of an application (e.g. creating message objects, DTO's, etc.).
Another place where a fluent interface can add value is for implementing behavior on a domain entity. Taking the same example from my previous post, where we have a domain class named Document with the name of the author, a title and one or more associated tags. Suppose we have a command that needs to add a new Tag to the existing list of tags for a particular Document. We usually end up with code like this:
The usual mistake I see a lot is to let the AddTag method directly take a Tag object. However, in this case the Document class is the aggregate root where Tag is merely a value object that lives within the boundaries of its aggregate root. This means that the aggregate root is responsible for creating instances of a Tag (also check out this post from Udi Dahan).
Lets make this code a bit more fluent. In my previous post, I provided a separate expression builder for creating new Tag objects. This TagBuilder is already used by the expression builder that creates Document objects.
Now lets reuse this builder class for our domain method that adds a new Tag for a Document. This is how the AddTag method is implemented:And this is how the calling code looks:
I have to admit that it does involve some overkill for this simple example. However, the code becomes a lot more clear when you have to provide a couple of more arguments to a domain method. Again, not everything is a nail for this shiny hammer. But it does bring some nice, readable code when needed. Here's another example that attaches the data of a file to a Document:
public class Document
{
var IList _tags = new List();
...
public void AddTag(String name)
{
var newTag = new Tag(name);
_tags.Add(newTag);
}
}
The fact that we can just reuse an existing expression builder is also a clear advantage.
Till next time