Needless Extension Methods from a developer in love with Fluent Interfaces

Building APIs that provide a so-called fluent interface seems to be all the rage right now in .NET development and I will be the first to step up and agree that in many places there is merit to this approach — done right, it can provide clarity and value to classes and make the methods and properties on them more discoverable to developers unfamiliar with them.

The other day I was reading a blog post (sorry, I don’t recall which one else I’d provide a link) that suggested that you could improve the readability of your unit tests by introducing a fluent interface to your objects that would make it easier/simpler/more readable to set them up to participate in the unit test.  On its surface, this seemed intriguing to me until I was presented just the other day with code from someone who clearly took this idea to a ridiculous extreme.

Take a look and let me know your thoughts (note I have intentionally simplified this example for the sake of this post from the more complex context of the actual problem)…

The System Under Test (SUT)

Let’s assume we have a Customer class as so…

    public class Customer
    {
        private string _firstname;
        private string _lastname;

        public string Firstname
        {
            get { return _firstname; }
            set { _firstname = value; }
        }

        public string Lastname
        {
            get { return _lastname; }
            set { _lastname = value; }
        }
    }

Nothing at all odd going on there.  Now let’s assume that as all good developers do, we now want to write a unit test that ensures we can create a customer, set its first and last names, and have those same values returned to us (note that I am intentionally condensing this test down into a single test when in fact each of these things really should be tested independently of each other in separate tests).

The Traditional SUT setup

This is probably the traditional way to code this test…

[Test]
public void CreateNewCustomerTheLongWay()
{
    Customer customer = new Customer();
    customer.Firstname = "Steve";
    customer.Lastname = "Bohlen";
    
    Assert.IsNotNull(customer);
    Assert.AreEqual("Steve", customer.Firstname);
    Assert.AreEqual("Bohlen", customer.Lastname);
}

Extension Methods

The developer in this case however decided that a fluent interface for the Customer class would help facilitate easy-to-read tests and make it simpler to set up instances of the Customer class to be used in the testing.  In order to not ‘clutter up’ the actual class definition for the Customer itself, this developer authored some C# 3.0 extension methods to facilitate testing the Customer class as so…

public static class CustomerExtensions
{
    public static Customer WithFirstname(this Customer customer, string firstname)
    {
        customer.Firstname = firstname;
        return customer;
    }

    public static Customer WithLastname(this Customer customer, string lastname)
    {
        customer.Lastname = lastname;
        return customer;
    }
}

This little sleight-of-hand of extension methods allowed writing the same tests as above leveraging the ‘fluent interface’ to set up the Customer instance in a brief one-liner as so…

The Fluent-Interface SUT setup

[Test]
public void CreateNewCustomerUsingFluentInterface()
{
    Customer customer = new Customer().WithFirstname("Steve").WithLastname("Bohlen");

    Assert.IsNotNull(customer);
    Assert.AreEqual("Steve", customer.Firstname);
    Assert.AreEqual("Bohlen", customer.Lastname);
}

While as mentioned I do agree that fluent interfaces to the methods and properties of classes can be a good thing (tending to increase the signal-to-noise ratio in code), this is (to me) clearly a case of a solution in search of a problem when in-line property-initialization could be used to accomplish the exact same thing (setting up the Customer object for the test in a terse one-liner) as in…

SUT setup using in-line property-initializers

[Test]
public void CreateNewCustomerUsingInlinePropertyInitialization()
{
    Customer customer = new Customer() { Firstname = "Steve", Lastname = "Bohlen" };
    
    Assert.IsNotNull(customer);
    Assert.AreEqual("Steve", customer.Firstname);
    Assert.AreEqual("Bohlen", customer.Lastname);
}

What’s more Clear?

Its not at all clear to me that the fluent-interface-based line of…

Customer customer = new Customer().WithFirstname("Steve").WithLastname("Bohlen");

…is any clearer at all than the in-line property-initialization version of…

Customer customer = new Customer() { Firstname = "Steve", Lastname = "Bohlen" };

…and the non-extension-method version doesn’t rely on maintaining the guts of the ‘fluent interface plumbing’ at all.  Note that its also possible to put the meat of the Fluent Interface code into the main Customer class definition too — extension methods were just chosen by the developer in this case to avoid ‘cluttering’ the Customer class with the fluent interface plumbing (return this, etc.) but this is a matter of taste more than anything else.

Summary

This isn’t intended as an indictment of fluent interfaces on objects since as I mentioned in the beginning I am generally a fan of this style of exposing an API in many cases.  This  is instead an indictment of the "use the paradigm that’s most popular today even where other more appropriate techniques are…more appropriate smile_sarcastic" style of development where the bandwagon seems to get trotted out in all kinds of unnecessary places and as a result ends up polluting an otherwise good idea with its own inappropriate usages.