C# Builder pattern with inheritance

The Builder pattern is very helpful in case you need to encapsulate and simplify creation of a complex object. Together with the fluent interface pattern it can result in a very nice API that can be a part of your library and is immediately clear and usable for other developers. Now what if we invite inheritance to the party?

Builder: The Inherited One

Suppose we want to create a fluent builder for two inherited types of an abstract   Game  class – LocalGame  and OnlineGame . Both types of games have some behaviors in common (like game board size, level), but each of them hase some additional setup steps, which are specific for that concrete type of game (local game my have a AI difficulty setting, on-line game may require the URL of the server we want to play on).

The abstract GameBuilder  could look like this:

And its inherited versions  LocalGameBuilder  and OnlineGameBuilder:

We can immediately see one issue with this code. The Build  method, defined as abstract in the GameBuilder , returns the base Game  type. This is certainly prone to errors, because the  LocalGameBuilder  could now produce any kind of game:

We need to find a way to make the return type of the Build  method strongly typed according to the specific builder.

Generic builder

Generics are part of C# since version 2.0 and are here to rescue us!

We can make the abstract  GameBuilder  generic, so that the type returned from the Build  is the concrete game type the inherited builder produces:

Note that we are also making sure, that the type parameter is a child of the base Game  class using the where generic type constraint.

The concrete builder can now just specify the type:

So far so good. Even our fluent API seems to be working well:

But everything is not peaches and cream. What if we change the order of the method calls in the chain?

We get an error on the third line – 'GameBuilder<OnlineGame>' does not contain a definition for 'ServerUrl' .

The reason is that the Level  method does not return OnlineGameBuilder , it returns just the plain old GameBuilder<OnlineGame>  which has no knowledge of ServerUrl  whatsoever.

Even more generic builder

Let’s revisit the abstract builder again and try to make its fluent methods able to return its specific derived type.

We make use of the so called Curiously Recurring Template Pattern which originates in C++, but we will make it usable in C#.

To pass the concrete builder type to the base, we add a new type parameter, which derives from GameBuilder  to GameBuilder  itself:

This is quite tricky to understand. We basically want the TBuilder  type parameter to actually be an implementation of the GameBuilder  which has the given game type as the first type parameter and itself as the TBuilder  type parameter.

It looks really weird in the definition itself, but it becomes much more clear with usage:

This enables us just what we wanted – to pass the concrete builder to the abstract builder for use.

Now we just have to resolve one more problem. The fluent methods need to return the instance of the class itself so that we can chain the calls:

This does not work! On the fourth line we are trying to return this , which just an GameBuilder<TGame, TBuilder> , not the derived builder ( TBuilder ).

Let’s help ourselves with a little hack. We will add a new abstract read-only property to the abstract GameBuilder :

protected abstract TBuilder BuilderInstance { get; }

This property will be implemented by the concrete builders and will allow them to return their own this  instance:

So now the base builder has not only access to the derived type in form of the TBuilder  type parameter, but also to the instance itself by virtue of the BuilderInstance  property without requiring casting. The fluent methods will now have the following form:

If we now use the API to create a game, we can see that no matter which method call order you use, we will always get back the correct specific builder.

The final version

Here is the final version of our completed builders:

Update: Improvement from Ondřej Kunc

There is a very nice tweak, which was pointed out to me by Ondřej Kunc in the comments of this article. Thank you for the great feedback, Ondřej!

It turns out that I was unnecessarily overcomplicating the this  handling with the abstract BuilderInstance  property. There is a much easier way, which doesn’t require the inherited builders to return their own instance (which is even a bit dangerous, because they could for instance return a new instance each time, which would destroy the builder’s functionality).

What we can do instead is to add a readonly field to the abstract GameBuilder and during contruction just cast this  to TBuilder  type and store the result in this field. We are guaranteed that this cast will succeed thanks to the generic constraints.

Summary

We have started out with a simple non-generic builder pattern, which was quite prone to errors. We extended it with generics, so that we can make sure that the builders do actually build the concrete types as they promise. Finally, the C# flavor of the curiously recurring template pattern helped us make the fluent API fully functional even in its generic form.

You can see and get the sample source code here on my GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*