我們力求頁面層代碼簡潔並具有較好的可讀性在ASPNET MVC的平台上我們以新的起點來實現這一目標MvcContribFluentHtml和Spark ViewEngine給我們做出了榜樣本文將以MvcContribFluentHtml為例探究它的實現機制:Fluent Interface
在MvcContribFluentHtml的應用中我們隨處可以見到下面的代碼:
< %= thisTextBox(x => xPersonName)Title(Enter the persons name)Label(Name:) %>
……
< %= thisSelect(x => xPersonGender)Options(ModelGenders)Size()Label(Gender:)
Title(Select the persons gender) %>
浏覽器中生成的代碼為:
< LABEL id=Person_Name_Label for=Person_Name>Name:< /LABEL>
< INPUT id=Person_Name title=Enter the persons name value=Jeremy maxLength= name=PersonName>
< SELECT id=Person_Gender title=Select the persons gender size= name=PersonGender>< OPTION selected value=M>Male< /OPTION>< OPTION value=F>Female< /OPTION>< /SELECT>
上面對動態生成TextBox和Select的代碼很有意思我們使用普通的方式在頁面上生成同樣的客戶端代碼CS代碼大致是這樣的:
Label label = new Label();
labelText = Name;
TextBox textbox= new TextBox();
textboxToolTip =Enter the persons name;
textboxID = No;
textboxID = PersonName;
而FluentHtml創建頁面元素的方式讓我們很容易聯想到StringBuilder的使用:
StringBuilder stringbuilder = new StringBuilder();
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方法:
public StringBuilder Append(string value)
{
if (value != null)
{
string stringValue = thism_StringValue;
IntPtr currentThread = ThreadInternalGetCurrentThread();
if (thism_currentThread != currentThread)
{
stringstringValue = stringGetStringForStringBuilder(stringValue stringValueCapacity);
}
int length = stringValueLength;
int requiredLength = length + valueLength;
if (thisNeedsAllocation(stringValue requiredLength))
{
string newString = thisGetNewString(stringValue requiredLength);
newStringAppendInPlace(value length);
thisReplaceString(currentThread newString);
}
else
{
stringValueAppendInPlace(value length);
thisReplaceString(currentThread stringValue);
}
}
return this;
}
閱讀這段有兩個特別要注意的點:方法的返回值是StringBuilder類型 最後一句:return this;為了深刻理解我們寫一個簡單的StringBuilder:
public interface IContentBuilder
{
void WriteContent();
IContentBuilder Append(string partialContent);
}
public class TestContentBuilder : IContentBuilder
{
string temp;
#region IContentBuilder Members
void IContentBuilderWriteContent()
{
ConsoleWrite(temp);
}
IContentBuilder IContentBuilderAppend(string partialContent)
{
temp += partialContent;
return this;
}
#endregion
}
… …
//調用代碼
IContentBuilder t = new TestContentBuilder();
tAppend(test)Append(Hello)WriteContent();
跑一下代碼和StringBuilder效果是一樣的從上面的應用也可以看出:Fluent Interface經常用來完成對象的構造和屬性賦值
言歸正傳:FluentHTML了解了Fluent Interface我們來看一下MVCContribFluentHTML的實現
From:http://tw.wingwit.com/Article/program/net/201311/13374.html