In the previous post, we have been talking about Builder and the Fluent Builder design patternsBuilder and the Fluent Builder design patterns. So, we strongly recommend reading that one before you continue with this post if you are not familiar with the Fluent Builder pattern. In this post, we are going to get a Fluent Builder to a higher level and show how we can use generics while inheriting from another Fluent Builder.

When builders inherit from other builders, nothing particular is going to happen and everything should remain the same. But if one Fluent Builder inherits from another one, well, we are going to have a problem with chaining actions. Therefore, we are going to use a Recursive Generics approach to enable the default behavior of our fluent interfaces.

You can download the source code from here: Fluent Builder With Recursive Generics – Source Code

This article is divided into the following sections:

The Problem With the Fluent Builder Inheritance

Let’s imagine that we want to build an Employee object. So obviously, the first thing to do is to create our model class:

To continue on, we are going to create a builder class to build the Name part of our object:

Now, we can create another builder class to build the Position part, and that class is going to inherit from the EmployeeInfoBuilder class because we want to reuse our employee object:

Finally, we can start making calls towards this builder classes:

Fluent Builder Recursive Generics - Chain problem

But, as we can see, we are not able to create a required object. This is because the SetName method will return an instance of type EmployeeInfoBuilder which currently doesn’t implement or inherit the AtPosition method. This is quite okay since the EmployeeInfoBuilder class is a higher order class and the EmployeePositionBuilder class inherits from it, and not another way around.

So, we need to find a solution to propagate information from the derived class to the base class. And the solution is in recursive generics approach.

Implementing Recursive Generics with Fluent Builder

So, let’s start with the EmployeeBuilder abstract class, which will be responsible for instantiating and providing our employee object:

Once we are done, we can continue to the EmployeeInfoBuilder modification. We have seen that the SetName can’t return the EmployeeInfoBuilder type, it needs to return a generic type. Having this in mind, let’s modify our class:

Ok, what???

Well, it is not that complicated as it may look like at a first glance.

We’ve said that the SetName method needs to return a generic type, therefore our class is generic as well. It needs to inherit from the EmployeeBuilder class because we need that employee object. Finally, we must make sure to get the right type for the T type in our class. We can achieve this by restricting our T type to the EmployeeInfoBuilder type.

Now we can continue to the EmployeePositionBuilder modification:

By doing this we enabled inheritance in both of these classes. They support the fluent builder interface approach and they can return the required type now.

This is very useful in our case because our employee needs his salary. We can easily add the salary now by using the WithSalary method of the EmployeeSalaryBuilder class:

At this moment, we know how to create Builder classes with recursive generics.

But we can’t start building our object yet.

That’s because it is not entirely clear which type we should when instantiating the EmployeeInfoBuilder class.

Therefore, we are going to create an API to allow the building of our object:

Now we can start building our object in a fluent way:

Awesome.

Now we know how to enable fluent interface inheritance by using a recursive generics approach.

Conclusion

In the next article, which is going to be related to the Builder pattern again, we are going to talk about Faceted Builder and show you how to use a facade to create an object which requires more than one builder class.

If you have enjoyed reading this article and if you would like to receive the notifications about the freshly published .NET Core content we encourage you to subscribe to our blog.