Sep 19, 2010

Hijacking language features for syntactic sugar – not always a good idea

Hijacking language features to support syntactic sugar is not always a good idea.

I was working on a little pet project and I decided to try and add some syntactic sugar to my pages. I have a navigation menu and I would like page to specify which item in the navigation menu is the current one so that it can be highlighted. The navigation menu is a partial view and I would like to be able to write something like this:

<% Html.RenderPartial("Navigation", currentItem => "Log in"); %>

Notice the current item part – this looks like a ruby hash and it’s nice and descriptive. Making this work on the other hand is pretty sketchy. First we need an extension method for HtmlHelper that can actually take Func<string, string> as a parameter. Here’s the implementation I came up with:

    public static class RenderPartialExtensions
    {
        public static void RenderPartial(this HtmlHelper helper, string partialViewName, Func<string,string> currentItem)
        {
            helper.RenderPartial(partialViewName, currentItem(string.Empty));
        }
    }

All I do here is invoke the Func<string, string> with string.Empty as parameter. Really? Pretty shady. There’s also a small issue with the “currentItem” part. I can’t think of a way to make sure it’s called that which defeats the purpose. I decided to abandon this idea, there are simply too many things wrong here.

For now I ended up creating a NavigationModel that has a CurrentItemName property and just use it that way. The syntax is still nice and readable and it has none of the smells of the previous try. If somebody were to come up with a cleaner implementation I might be persuaded still. The final usage looks like this:

<% Html.RenderPartial("Navigation", new NavigationModel { CurrentItemName = "Log in" }); %>