我们力求页面层代码简洁并具有较好的可读性在ASPNET MVC的平台上我们以新的起点来实现这一目标MvcContribFluentHtml和Spark ViewEngine给我们做出了榜样本文将以MvcContribFluentHtml为例探究它的实现机制:Fluent Interface
在MvcContribFluentHtml的应用中我们随处可以见到下面的代码:
<%=thisTextBox(x=>xPersonName)Title(Enterthepersonsname)Label(Name:)%>
……
<%=thisSelect(x=>xPersonGender)Options(ModelGenders)Size()Label(Gender:)
Title(Selectthepersonsgender)%>
浏览器中生成的代码为:
<LABELid=Person_Name_Labelfor=Person_Name>Name:</LABEL>
<INPUTid=Person_Nametitle=Enterthepersonsnamevalue=JeremymaxLength=name=PersonName>
<SELECTid=Person_Gendertitle=Selectthepersonsgendersize=name=PersonGender><OPTIONselectedvalue=M>Male</OPTION><OPTIONvalue=F>Female</OPTION></SELECT>
上面对动态生成TextBox和Select的代码很有意思我们使用普通的方式在页面上生成同样的客户端代码CS代码大致是这样的:
Labellabel=newLabel();
labelText=Name;
TextBoxtextbox=newTextBox();
textboxToolTip=Enterthepersonsname;
textboxID=No;
textboxID=PersonName;
而FluentHtml创建页面元素的方式让我们很容易联想到StringBuilder的使用:
StringBuilderstringbuilder=newStringBuilder();
stringbuilderAppend(Hello)Append()Append(World!);
Fulent Interface 这种实现编程方式就是Fluent Interface这并不是什么新概念年Eric Evans 和Martin Fowler就为这种实现方式命名源文档 <; 可以通过维基百科中对Fluent Interface的描述获得一个基本的了解: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
我们分解上面的话:
它是面向对象API的一种实现方式目的是增加代码的可读性既然我们最熟悉的是StringBuilder我们就从这个线索追下去:打开Reflector很容易找到StringBuilder的Append方法:
publicStringBuilderAppend(stringvalue)
{
if(value!=null)
{
stringstringValue=thism_StringValue;
IntPtrcurrentThread=ThreadInternalGetCurrentThread();
if(thism_currentThread!=currentThread)
{
stringstringValue=stringGetStringForStringBuilder(stringValuestringValueCapacity);
}
intlength=stringValueLength;
intrequiredLength=length+valueLength;
if(thisNeedsAllocation(stringValuerequiredLength))
{
stringnewString=thisGetNewString(stringValuerequiredLength);
newStringAppendInPlace(valuelength);
thisReplaceString(currentThreadnewString);
}
else
{
stringValueAppendInPlace(valuelength);
thisReplaceString(currentThreadstringValue);
}
}
returnthis;
}
阅读这段有两个特别要注意的点:方法的返回值是StringBuilder类型 最后一句:return this;为了深刻理解我们写一个简单的StringBuilder:
publicinterfaceIContentBuilder
{
voidWriteContent();
IContentBuilderAppend(stringpartialContent);
}
publicclassTestContentBuilder:IContentBuilder
{
stringtemp;
#regionIContentBuilderMembers
voidIContentBuilderWriteContent()
{
ConsoleWrite(temp);
}
IContentBuilderIContentBuilderAppend(stringpartialContent)
{
temp+=partialContent;
returnthis;
}
#endregion
}
……
//调用代码
IContentBuildert=newTestContentBuilder();
tAppend(test)Append(Hello)WriteContent();
跑一下代码和StringBuilder效果是一样的从上面的应用也可以看出:Fluent Interface经常用来完成对象的构造和属性赋值
言归正传:FluentHTML了解了Fluent Interface我们来看一下MVCContribFluentHTML的实现