Designing a flexible Fluent API - Part 2
In the previous post, we saw a real life requirement (a custom view engine) and the intended API that the developers would use.
Let’s begin with some of the basic constructs used:
The View class is the root component that contains all of our other components. As you can see it is an IComponentContainer. In the code displayed in the previous post, you may remember a Panel component that contained some other components. A Panel is also an IComponentContainer.
Bear with me, there is a reason I am explaining all of this.
Lets see the TextBox component:
Now, let’s get into the component builders that provide the fluent API we saw in the previous post.
Ok, so the TextBoxBuilder is where the textbox specific options will be and each call to an option will return the builder instance so that the chain can keep going.
But what about all those properties that are inherited from the common interfaces, like ICustomCssEnabledComponent and IEventEnabledComponent. We do not want to duplicate the code for handling these properties in every builder, right?
If we try to solve the problem using inheritance, like having TextBoxBuilder inherit from a base ComponentBuilder class that contains those common options, we run into a flexibility problem.
What happens if an other component builder doesn’t need all of those methods? We would expose methods that are not appropriate is some cases and this is bad.
In the next post we will see how we are going to solve this problem, using C#’s extension methods.