6 years ago by James Hickey
Ever find yourself frustrated with 3rd party libraries that are supposed to be useful? Easy to use?
Ever gone back to some nice/reusable class that you built a few weeks ago only to realize you have no idea how to get started with it. Nothing obviously sticks out as a starting point?
So, you decide to check out the documentation only to spend an hour trying to figure out how to get started with the one thing you need the library for!
I've been there so many times! Throughout my career I've always wondered if there was a way to build reusable pieces that are just 100% plain and obvious to use. Something that just guides you through the proper usage.
Let's try to learn from the best. The tools that are the easiest to use. Here are a few tools that I personally find are enjoyable to use:
These represent, to me, some of the easiest-to-use yet powerful tools I've encountered in my career.
I don't use JQuery anymore, nor will I (by choice). But everyone would agree that JQuery made working with the DOM enjoyable compared to the native tools at the time.
So - what do all of these tools have in common? What makes them so easy to use?
They are (mostly) Fluent APIs.
The term "fluent" has the connotation that "fluent API" somehow relates to (spoken) languages. You can be fluent in English, for example.
Fluent interfaces are a style of programming that focuses on how your code reads easily and naturally - like you are reading a book.
For example,in .NET Core you might find code like this:
app.UseDeveloperExceptionPage() .UseDatabaseErrorPage();
This is very easy to understand and to read. You intend to use the developer exception page (which has nice debugging info for developers). You also wish to use some special error page when you get database errors.
Let's look at another example:
services .AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
In this example, calling the "AddMvc" method unlocks access to other methods that only make sense within that specific context.
This to me is the most powerful aspect of fluent interfaces - they only let you use what makes sense to use within the current context.
When a fluent API is done properly you shouldn't be able to:
If you want to continue reading about these ideas you can read this post where I discuss more benefits you get with fluent APIs.
For the reasons above (and the reasons in the post I linked to) I opted to use a fluent API when writing Coravel. I think this is one of the main reasons that people are using it - it's so easy to work with.
For example, can you figure out what this code is intending to do?
This is how easy code written in a fluent style can be to understand. There's no mistaking what this code does.
Take this example of me using Coravel in Visual Studio Code:
When someone wants to schedule something they get access to new methods. These methods are only ever available in the context of scheduling something.
Also notice that only methods related to scheduling are available. There's no bleeding of methods from other contexts here.
After selecting the frequency those methods are gone and you get access to a new group of selections:
So you're dying to know - how do I actually build one?
Building basic fluent APIs can actually be really simple. The key "trick" is that the methods in your class can return an interface that restricts what methods the caller can use.
Here's what a working example might look like:
public class MyFluentClass : ICalculation, IResult
{
private int _value;
private int _result;
private MyFluentClass() { }
public static ICalculation WithValue(int value)
{
return new MyFluentClass
{
_value = value
};
}
public IResult Add(int toAdd)
{
this._result = this._value + toAdd;
return this;
}
public IResult Subtract(int toSubtract)
{
this._result = this._value - toSubtract;
return this;
}
public int Result() => this._result;
}
public interface ICalculation
{
IResult Add(int toAdd);
IResult Subtract(int toSubtract);
}
public interface IResult
{
int Result();
}
Things to notice:
Here's what it looks like in action:
Thanks for taking the time to go through this - I hope you learned something new and enjoyed the content!
By the way, this is part 2 of my series "What I've Learned So Far Building Coravel". Here are the other parts of the series:
Part 1 - What I've Learned So Far Building Coravel (Open Source .NET Core Tooling)
Part 3 - .NET Core Dependency Injection: Everything You Ought To Know
Hello, I'm Corstiaan. I'm a software developer from the Netherlands and I manage BuiltWithDot.Net. I created this site as a place where developers working with .net technology can showcase their projects and inspire other developers.
There's so much you can build with .net these days that I thought it would be nice to have a corner of the web dedicated to the breadth of .net. Enjoy!
We write about effective c# coding methods all the time. Sign up below for updates.
Great! Click the link in the e-mail to confirm. Check the spam folder if you can't find it.
No spam. Unsubscribe any time.
© 2024 - created by Corstiaan Hesselink - submit project - RSS feed - contact