What is a Fluent Interface?
When developing software, it is important that the code that you write is easy to understand in order that it can be maintained at a later date. There are many ways in which you can structure your classes in order to achieve this and various guidelines, such as the five SOLID principles. One way to achieve improved readability for your source code is to develop libraries with fluent interfaces.
Fluent interfaces allow code to be created that appears similar to natural language, when the symbols that decorate methods are ignored. This involves choosing member names that can be combined in ways that mirror words in a language such as English. The words are then combined using method chaining, where each method returns a result that can be acted upon by the next call in the sequence. However, fluent interfaces are not designed for method chaining alone.
To understand the difference between a fluent and non-fluent interface, let's look at an example. The code below uses method chaining but if the member names are read out loud, the meaning is not perfectly clear. The code calculates the date and time one week from the current date at 9:30am.
DateTime time = DateTime.Now.AddDays(7).Date.AddHours(9).AddMinutes(30);
This simple example is reasonably easy to understand for a developer but as the complexity grows it could become more difficult. If we convert the code to use a more fluent syntax, we can make its purpose clearer. The code below, read aloud, is "One week hence at 9:30".
DateTime time = 1.Week().Hence().At(9, 30);
Fluent interfaces are used widely in frameworks and library code. Two common examples that have been examined in earlier articles are Language-Integrated Query (LINQ) and Moq. You can create your own fluent interfaces by adding suitably named methods to your classes. You can also take advantage of C# 3.0's extension methods to add fluent-style methods to existing classes, including .NET framework types. We'll use this technique in the following sections to create a small fluent interface for date and time processing that supports the code example above.
Integer Extensions
In the fluent example code above, the first method used is "Week". This is an extension method of the integer type that creates a TimeSpan value representing the specified number of weeks. The code below shows how the method is created, as well as several other integer extension methods that create TimeSpans for days, hours and minutes.
public static class FluentTimeExtensions
{
public static TimeSpan Days(this int number)
{
return new TimeSpan(number, 0, 0, 0);
}
public static TimeSpan Hours(this int number)
{
return new TimeSpan(number, 0, 0);
}
Read more: BlackWasp
QR: