Wednesday, September 18, 2013

Fluent MVC Extensions

In my previous blog I provided an overview of the MVC Extensions (HTML Helpers) and creating a custom extension. If you haven’t look at my previous blog, I recommend going through that blog.

In this blog I will show how to create a custom MVC Extensions using the Fluent Interface, which is the gateway for creating complex HTML Helpers.
Fluent API

The elegant way to create a complex HTML Extensions is to use the Fluent API approach. Below is the quote from Wikipedia on the Fluent Interface

In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide for more readable code.

A fluent interface is normally implemented by using method chaining to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining [1]). Generally, the context is
                ·         defined through the return value of a called method
                 ·         self-referential, where the new context is equivalent to the last context
                 ·         terminated through the return of a void context.

The key to the fluent interface is method chaining. The fluent interface was heavily used in the .NET framework. Below is an example of using the fluent interface

IEnumerable<string> query = translations
                                                .Where   (t => t.Key.Contains ("a"))
                                                .OrderBy (t => t.Value.Length)
                                                .Select  (t => t.Value.ToUpper());

 As you see all the methods (Where, OrderBy, Select) are chained together thus providing a seamless interface to the developers. There is no limitation on the number of methods you can chain.

We can incorporate this fluent interface in our custom Label HTML Extension. With the fluent interface our call to the label will be transformed as follows:

@(Html.FluentLabel()
               .Target("firstName")
               .Text("First Name")
              )

 With the fluent interface the properties will be transposed to the methods and these methods will be chained together.

Method Chaining Pattern

Method Chaining is a technique in which every method returns the current object, which it is part of, thus allowing the calls to be chained together in a single statement. In our custom extension Target and Text methods are stacked on another and if needed we can continue this cascading to any number of methods. Below is the Target method’s code which demonstrates this method chaining pattern.

        public Label Target(string target)
        {
            this.target = target;
            return this;
        }

 As you see in the above code, at the end the method returns the current object, which is Label object.

Fluent API in Action

Below is the complete code of our custom Label HTML Helper using fluent interface with methods Target and Text chaining together to form a cohesively unit

    public static class LabelExtensions
    {
        public static Label FluentLabel(this HtmlHelper helper)
        {
            return new Label();
        }
    }

    public class Label
    {
        private string target, text;

        public Label Target(string target)
        {
            this.target = target;
            return this;
        }

        public Label Text(string text)
        {
            this.text = text;
            return this;
        }

        public override string ToString()
        {
            return String.Format("<label for='{0}'>{1}</label>Fluent", target, text); ;
        }
    }

This above custom Label extension can be used in the View as follows:

@(Html.FluentLabel()
        .Target("firstName")
        .Text("First Name")
            )

As you see the Fluent interface provides an easy infrastructure for building complex MVC Extensions.
If we are building a library of MVC Extensions, such as Juime (JQuery UI MVC Extensions), we need more than fluent interface. We have to couple this fluent interface with builder pattern. In my next blog I will walk you through the builder pattern and how it can be applied to build MVC Extensions.

2 comments:

  1. Or one can save all the typing, string fomatting and type designing and use the wonderful HtmlTags library: http://www.nuget.org/packages/HtmlTags/

    ReplyDelete
    Replies
    1. Daniel, Microsoft has TagBuilder object which is similar to your HtmlTags.
      http://www.asp.net/mvc/tutorials/older-versions/views/using-the-tagbuilder-class-to-build-html-helpers-cs

      Anyway my intent in this blog is to focus on creating the fluent extensions and not on how to generate the Html string.

      Delete