In Martin Fowler’s “famous” article about fluent interfaces, he talks about how it’s beneficial (when using strongly typed languages) to have the return type of your fluent method be flexible. We’ll be looking at this advanced fluent interface technique today.

Why?

Some benefits of building your fluent objects this way are:

  • Restrict differing paths of logic.
  • Enable differing paths of logic.
  • Better IDE code completion (as Fowler mentions in his article above - this makes your fluent objects more like “a wizard in the IDE”)

An Example Of Advanced Fluent Interfaces From C#’s LINQ

I want to use a simple example that most C# / .NET developers will be familiar with - from LINQ.

Whenever you call the OrderBy method in LINQ, that method will actually give you new methods that you are able to call (e.g. ThenBy and ThenByDescending).

someIEnumerable
     .OrderBy(item => item.SomeProp) // This gives access to "ThenBy()"
     .ThenBy(item => item.SomeOtherProp);

It doesn’t make sense to perform ThenBy on it’s own. It only makes sense when you are currently ordering the elements in your collection, and you further want to order.

How Does This Happen!?

The way to perform this is very simple - and flexible. Anytime you want your fluent object to return an “alternate path” (i.e. restrict or add methods that are accessible to the caller) you just return the fluent object casted to an interface (which includes or excludes methods you require).

For example, LINQ methods (normally) return an object using the IEnumerable interface. But when you call OrderBy, you get an IOrderedEnumerable object.

The IOrderedEnumerable interface inherits from IEnumerable - so it has all the methods you normally would have access to. But - it also defines the extra ThenBy and ThenByDescending methods.

New Site!

I’ll be writing new content over at my new site/blog. Check it out!

If You Enjoyed This…

I’ve been writing about Fluent Interfaces and Functional Programming lately - here are some related posts:

Keep In Touch

Don’t forget to connect with me on twitter or LinkedIn!