How to write Fluent Api in C#

For the first serious post, I’ve decided to make this tutorial. Fluent api stuff isn’t very complicated, but when I was searching on how to write one I’ve failed to find detailed explanation on how to do it. Plus, I’ve run into tons of bad examples…

A side note before beggining. Making fluent api isn’t complicated, but it can get messy quickly. So plan ahead. For that reason, I’m about to make two of them. Barebones introductory one, and then something more complex.

Fluent Api, or Fluent Interface Pattern is a way to neatly chain functions in your code. The best example is https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/. Onward to making our own.
Suppose we have the following class:

Now we wanna make a secretary object out of it. We also want a young secretary, between 22 and 28 years of age, with some sexy name of our choosing (talk about objectifying women). Regular way of doing this would be:

Instead the aim is to make it like this:

First, we need to make WomanScaffolder class. Duh…

Notice the keyword sealed. It’s a common and good practice. We don’t have any reason to inherit this class anyway.
Since this scaffolder class eventually returns object of type Woman, we need to keep that object within the class, so we can modify it. One more thing, if you check out the picture above, you’ll notice that there’s no new keyword in front of WomanScaffolder. We are gonna keep the constructor private, and access this class in a different way.

To make chaining our functions possible, we must put those functions into interfaces. WomanScaffolder class will then implement them. These interfaces also control the order in which you can chain them. For now, the most simple version is this: you make the First interface, which has a function that returns Second interface, which has a function that returns Third interface, and so on. Planning this is the hardest part..

In the code above, you’ll see that I have three methods. Create(), Name() and Age(). Ignore Create() for the moment. I want to focus on interfaces first. For simplicity I’m gonna call them IFirstFunctions and ISecondFunctions for order clarity.

Now the implementation:

Now, we’re missing a way to access IFirstFunctions. This is done through that Create() function. It’s a static method that will call WomanScaffolder class constructor, and return IFirstFunctions, like this:

That’s it. It is fully functional. However, I do not like the layout. This Create function would make more sense at the end of the chain. Something to indicate ending. We also shouldn’t be limited by order. Maybe you don’t want to specify age, just the name. Also, maybe the name of the secretary would be some variable, not hard coded string, and we wanna have validation for that. So, I’ll modify the Create() function, and WomanScaffolder constructor like this:

This is the new entry point now. I’ll also modify the interfaces that we had, and add another one called ICheckout.

The Create() method now goes at the end of the chain, and it can be called anytime. This is why ICheckout is implemented by every other interface. Finally, our WomanScaffolder class looks like this:

The implemented validation is kinda crappy… Oh well, fits nicely on printscreen. Go ahead, type: var secretary = WomanScaffolder.Name(“Nia”) into your Main() and play with it.

5 comments Write a comment

  1. brockness

    Interesting tutorial. However the images – where all the actual code is – are way too small to read

  2. Please link to the images in their original size and don’t let them autosize by wordpress – I can _barely_ read the text (I have some eye resolution problems which can’t be corrected)

  3. lanitasupherb

    Thank you for the reminder. I started learning API when I joined steemit a few years ago. With all of the tech changes we are experiencing, it would be a great inspiration for all to put learning API basics in to their life style.

    Awesome info, keep doing you!

  4. phq

    First, thanks for the feedback. I appreciate it. I’m aware of the image problem. I was trying to figure out how to solve this. Unfortunately, Vivaldi’s blog doesn’t support some plugin for code rendering as far as I know. I’m experimenting with image sizes now, but next time I’ll probably include a pdf or html page for download

Leave a Reply