I’m still undecided as to whether I like fluent interface API designs or not – certainly, when written well, they add a certain readability to code, but they can also easily become overly verbose. However this post is not about whether they’re good or bad, but more about how we might implement such a pattern.
The API pattern “Fluent Interface” was coined in 2005 (according to Wikipedia) but the basic premise of the pattern has been around for far longer.
The general idea is to design an API which is more readable and properties etc. are assigned using cascading methods (or method chaining).
Let’s see an example
So let’s look at a simple example (using object initializer syntax)
I’m not going to bother including the Result class in this post as the full source can be found on my GitHub repos
var r = Result { Value = 0, StatusCode = 102, Message = "Failed to load" };
a possible API using a Fluent interface might be
var r = ResultBuilder .Create() .WithValue(0) .WithStatusCode(102) .WithMessage("Failed to load") .Build();
We’re actually using the builder class to create the Result object and set the properties/fields on it. In this example we’re not actually creating the Result object until the Build method is called. In some implementations we might create the Result object upfront, i.e. when we first start supplying properties.
Implementation
The basics of method chaining are simple enough. Your builder methods return an instance to itself, i.e. return this or a copy instance. In the case of the builder class we’re going to implement, we’re going to return an instance of the builder from the Create method, then we’ll create expressions for each WithXXX method to allow us to build the Result object when we’re finished. Finally the Build method will create the Result and apply the expressions against it.
Here’s the source for the ResultBuilder
public class ResultBuilder { private readonly List<Action<Result>> _actions = new List<Action<Result>>(); public static ResultBuilder Create() { return new ResultBuilder(); } public ResultBuilder WithValue(int value) { _actions.Add(a => a.Value = value); return this; } public ResultBuilder WithStatusCode(int statusCode) { _actions.Add(a => a.StatusCode = statusCode); return this; } public ResultBuilder WithMessage(string message) { _actions.Add(a => a.Message = message); return this; } public Result Build() { var result = new Result(); foreach(var action in _actions) action(result); return result; } }
As you can see, we have a way (in this case, a static method) to create the builder, then we use the fluent API of the builder to create the expressions that will be applied to the object we intend to build. This means we could create a builder to acts as a factory method to create pre-defined Result objects.
If we don’t need the lazy creation portion of the code, i.e. we’re always going to create a result then we could ofcourse simply use something like
public class ResultBuilder { private readonly Result result = new Result(); public static ResultBuilder Create() { return new ResultBuilder(); } public ResultBuilder WithValue(int value) { result.Value = value; return this; } public ResultBuilder WithStatusCode(int statusCode) { result.StatusCode = statusCode; return this; } public ResultBuilder WithMessage(string message) { result.Message = message; return this; } public Result Build() { return result; } }