To get a concise and more readable page code, we will use a new way in ASP .NET MVC platform。MvcContrib.FluentHtml and Spark ViewEngine has set an example to us. We will take MvcContrib.FluentHtml for an example to explore the mechanism of its realization: Fluent Interface.
In applications of MvcContrib.FluentHtml, we can see the following code everywhere.
< %= this.TextBox(x => x.Person.Name).Title (”Enter the person’s name”).Label (”Name :”) %> …… < %= this. Select(x => x.Person.Gender).Options (Model.Genders).Size (5).Label (”Gender :”) .Title (”Select the person’s gender”) %>
The generated codes in browser are:
< LABEL id=Person_Name_Label for=Person_Name>Name:< /LABEL> < INPUT id=Person_Name title=”Enter the person’s name” value=Jeremy maxLength=50 name=Person.Name> . < SELECT id=Person_Gender title=”Select the person’s gender” size=5 name=Person.Gender>< OPTION selected value=M>Male< /OPTION>< OPTION value=F>Female< /OPTION>< /SELECT>
Above these are the dynamically generated codes of TextBox and Select . The same client-side codes can be generated in the page with a common way. The CS code could be like this :
Label label = new Label();
label.Text = “Name”;
TextBox textbox= new TextBox();
textbox.ToolTip =”Enter the person’s name”;
textbox.ID = “No.10001″;
textbox.ID = “Person.Name”;
We ‘ll be easily triggered by the way FluentHtml create the page elements to use String Builder.
StringBuilder stringbuilder = new StringBuilder(); stringbuilder.Append(”Hello”).Append(” “).Append(”World!”);
Fluent Interface
Fluent Interface ,which was used to program like that , is not a new concept. In 2005, Eric Evans and Martin Fowler have named such way with Fluent Interface. The source document can be got a fundamental understanding from the following description:
In software engineering, a fluent interface (as first coined by Eric Evans and Martin Fowler) is a way of implementing an object oriented API in a way that aims to provide for more readable code.
Then ,we can get a better understanding from the meanings the words contain.
Firstly, a fluent interface a way of implementing an object oriented API .Its aims to provide for more readable code. Since StringBuilder is the most familiar to us , we continue to explore the programme from this clue: Open Reflector, then find the Append method of StringBuilder easily .
public StringBuilder Append(string value)
{ if (value != null)
{ string stringValue = this.m_StringValue;
IntPtr currentThread = Thread.InternalGetCurrentThread();
if (this.m_currentThread != currentThread)
{
stringstringValue = string.GetStringForStringBuilder(stringValue, stringValue.Capacity);
} int length = stringValue.Length;
int requiredLength = length + value.Length;
if (this.NeedsAllocation(stringValue, requiredLength))
{ string newString = this.GetNewString(stringValue, requiredLength);
newString.AppendInPlace(value, length);
this.ReplaceString(currentThread, newString);
}
else
{
stringValue.AppendInPlace(value, length);
this.ReplaceString(currentThread, stringValue);
}
} return this;
}
When reading about that , there are two particular points to note .1.The value the method will return is the type of StringBuilder .2.The last word :return this;.
To get a profound understanding, We show you a simple StringBuilder:
public interface IContentBuilder {
void WriteContent();
IContentBuilder Append(string partialContent);
} public class TestContentBuilder : IContentBuilder { string temp;
#region IContentBuilder Members void IContentBuilder.WriteContent() {
Console.Write(temp);
}
IContentBuilder IContentBuilder.Append(string partialContent) {
temp += partialContent;
return this;
} #endregion }
… … // IContentBuilder t = new TestContentBuilder(); t.Append(”test”).Append(”Hello”).WriteContent();
From the above applications,we can see : Fluent Interface is frequently used to complete Object structure and properties assignment .
Get down to business. From FluentHTML ,we know Fluent Interface .Then, we will show you how to realize MVCContrib.FluentHTML .
Firstly ,we will talk about its inheritance through Textbox.
public class TextBox : TextInput public abstract class TextInput : Input, ISupportsMaxLength where T : TextInput public abstract class Input : FormElement where T : Input, Ielement.
Generics are a high-level abstract algorithm.INPUT will lead me to learn the assigns:
public abstract class Input : FormElement where T : Input, Element {
protected object elementValue;
protected Input(string type, string name) : base(HtmlTag.Input, name)
{
builder.MergeAttribute(HtmlAttribute.Type, type, true);
} protected Input(string type, string name, MemberExpression forMember, IEnumerable behaviors) : base(HtmlTag.Input, name, forMember, behaviors)
{
builder.MergeAttribute(HtmlAttribute.Type, type, true);
} /// /// Set the ‘value’ attribute. /// /// The value for the attribute.
public virtual T Value(object value)
{ elementValue = value;
return (T)this;
}
/// /// Set the ’size’ attribute. /// /// The value for the attribute.
public virtual T Size(int value)
{ Attr(HtmlAttribute.Size, value);
return (T)this; } protected override void PreRender() { Attr(HtmlAttribute.Value, elementValue);
base.PreRender();
}
}
Take the method Size for example, we can see it is a typical realization of the Fluent Interface: public virtual T Size(int value) { Attr(HtmlAttribute.Size, value); return (T)this; }
When you read this ,you will find that words(the expression of Lambda ) a little strange.
this.TextBox(x => x.Person.Name).Title(”Enter the person’s name”).Label(”Name:”)
From the code of TextBox,we do not see the support of the Lambda expressions.
So, where is it ?Let me look at ViewDataContainerExtensions. Here is IViewDataCon.
namespace MvcContrib.FluentHtml {
/// /// Extensions to IViewDataContainer ///
public static class ViewDataContainerExtensions
{
/// /// Generate an HTML input element of type ‘text’ and set its value from ViewData based on the name provided. /// /// The view.
/// Value of the ‘name’ attribute of the element.Also used to derive the ‘id’ attribute.
public static TextBox TextBox(this IViewDataContainer view, string name)
{
return new TextBox(name).Value(view.ViewData.Eval(name));
} … … the Extension Method of tainer:Have a look at return new TextBox(name).Value(view.ViewData.Eval(name));So,here is the first step of the definition of method chain TextBOx.
The summary of FluntHtml and Fluent Interface.
In order to get a concise and simple html element structure in VIEW, We use htmlHelper.InputHelper in ASP.NET.In the page layer,HTML is Extension Method of htmlHelper. However, FluentHTML will be more flexible to provide .
Share This