Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Extension methods that add fluent elegance

Posted on October 20, 2010

Last night I was updating some integration tests for one of my projects. I have many test methods that configure a directory path from several sources of information and found that path concatenation often results in ugly unreadable code.

Consider the scenario where you have a base path to which you want to add several other directory names.

namespace ConsoleApplication1
{
    using System;
    using System.IO;
    
    class Program
    {
        static void Main(String[] args)
        {
            String basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            const String ProductName = "SomeProductName";
            String instanceName = Guid.NewGuid().ToString();
            const String dataName = "DataStore";
    
            String hardToReadEvaluation = Path.Combine(Path.Combine(Path.Combine(basePath, ProductName), instanceName), dataName);
    
            Console.WriteLine(hardToReadEvaluation);
            Console.ReadKey();
        }
    }
}

The statement with multiple Path.Combine evaluations is very difficult to read. A simple extension method can turn this into a fluent API design to achieve the same result and allow the intention of the code to be crystal clear.

namespace ConsoleApplication1
{
    using System;
    using System.IO;
    
    public static class Extensions
    {
        public static String AppendPath(this String basePath, String appendValue)
        {
            return Path.Combine(basePath, appendValue);
        }
    }
    
    class Program
    {
        static void Main(String[] args)
        {
            String basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            const String ProductName = "SomeProductName";
            String instanceName = Guid.NewGuid().ToString();
            const String dataName = "DataStore";
    
            String fluentEvaluation = basePath.AppendPath(ProductName).AppendPath(instanceName).AppendPath(dataName);
    
            Console.WriteLine(fluentEvaluation);
            Console.ReadKey();
        }
    }
}

The code is now much more readable. You no longer need to backtrack along the line of code to figure out which variables related to which operation in the evaluation as the code now reads fluently from left to right.