Fluent Domain Methods
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:
public class Document { var IList<Tag> _tags = new List<Tag>(); ... public void AddTag(String name) { var newTag = new Tag(name); _tags.Add(newTag); } }
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.
public interface ITagBuilder { void Named(String name); } public class TagBuilder : ITagBuilder { private readonly Action<Tag> _afterBuildAction; public TagBuilder(Action<Tag> afterBuildAction) { _afterBuildAction = afterBuildAction; } public void Named(String name) { var tag = new Tag(name); _afterBuildAction(tag); } }
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:
public ITagBuilder AddTag() { return new TagBuilder(newTag => _tags.Add(newTag)); }
And this is how the calling code looks:
document.AddTag().Named("Science"));
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:
document.Attach()
.FileWithName("The Universe in a Nutshell.pdf")
.AndData(new Byte[] { ... });
The fact that we can just reuse an existing expression builder is also a clear advantage.
Till next time



Pingback: Reflective Perspective - Chris Alcock » The Morning Brew #403
Pingback: Dew Drop – August 3, 2009 | Alvin Ashcraft's Morning Dew
Pingback: Summary 05.08.2009 « Bogdan Brinzarea’s blog