天天看點

提供第三種代碼生成方式——通過自定義BuildProvider為ASP.NET提供代碼生成 一、BuildProvider是什麼? 二、将XML表示的消息轉換成VB.NET或者C#代碼三、将XML轉換成CodeDOM四、自定義BuildProvider五、BuildProvider的應用

目錄 一、BuildProvider是什麼? 二、将XML表示的消息轉換成VB.NET或者C#代碼 三、将XML轉換成CodeDOM 四、自定義BuildProvider 五、BuildProvider的應用

對于ASP.NET應用的開發者來說,你可能不知道什麼是BuildProvider,但是你幾乎無時無刻不在使用它所帶來的代碼生成機制。當你建立一個.aspx檔案的時候,為什麼會自動建立對應源代碼?當你在該.aspx頁面中以XML的方式添加一個按鈕,源代碼中為什麼會自動添加一個同名的屬性。實際上,ASP.NET就是通過一個特殊的BuildProvider實作了将.aspx檔案内容轉換成相應的源代碼,這個特殊的.aspx檔案就是:PageBuildProvider。基于不同的檔案類型,ASP.NET會采用不同的BuildProvider進行源代碼的生成。比如UserControlBuildProvider和MasterPageBuildProvider分别實作了基于使用者控件檔案(.ascx)和主機闆頁(.master)的源代碼生成。你可以通過檢視%Windows%\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config看看在預設情況下使用的BuildProvider以及它基于的源檔案類型(擴充名)。

既然ASP.NET可以通過相應的BuildProvider為不同類型的檔案生成相應的源代碼,我們自然也能自定義BuildProvider實作我們希望的代碼生成機制。為了讓讀者和之前提供的兩種方式的代碼生成機制作一個對于,我們依然采用相同的應用場景:将以XML表示的資料轉換成代碼,以實作強類型程式設計。

可能有些人沒有看過之前的文章,是以在這裡我再次簡單介紹一些我們需要通過代碼生成機制實作的場景:無論對于怎麼樣的應用,我們都需要維護一系列的消息。消息的類型很多,比如驗證消息、确認消息、日志消息等。我們一般會将消息儲存在一個檔案或者資料庫中進行維護,并提供一些API來擷取相應的消息項。這些API一般都是基于消息的ID來擷取的,換句話說,消息擷取的方式是以一種“弱類型”的程式設計方式實作的。如果我們能夠根據消息存儲的内容動态地生成相應的C#或者VB.NET代碼,那麼我們就能夠以一種強類型的方式來擷取相應的消息項了。

比如說,現在我們定義了如下一個MessageEntry類型來表示一個消息條目。為了簡單,我們盡量簡化MessageEntry的定義,僅僅保留三個屬性Id、Value和Category。Category表示該消息條目所屬的類型,你可以根據具體的需要對其分類(比如根據子產品名稱或者Severity等)。Value是一個消息真實的内容,可以包含一些占位符({0},{1},…{N})。通過指定占位符對用的值,最中格式化後的文本通過Format傳回。

現在我們所有的消息定義在如下一個XML檔案中,<message>XML元素代碼一個具體的MessageEntry,相應的屬性(Attribute)和MessageEntry的屬性(Property)相對應。

在上面的XML中,定義了兩個類别(Validation和Confirmation)的三條MessageEntry。我們需要通過我們的代碼生成工具生成一個包含如下C#代碼的CS檔案。

現在我們才進行我們的重點,如何通過一個自定義的BuildProvider将以XML形式存儲的消息清單轉換成相應的C#或者VB.NET代碼。為此我們建立一個名為MessageBuildProvider的類,MessageBuildProvider繼承自抽象類BuildProvider。因為從XML到CodeDOM的轉換已經實作在了上面的CodeGenerator類中,MessageBuildProvider的定義很簡單。

自定義的BuildProvider以配置的方式和源檔案的類型(擴充名),在這裡我們通過一個擴充名為.msg(不代表OutLook的消息檔案)來表示上述的存儲消息清單的XML。那麼,你可以建立一個WebSite,并添加對定義了MessageBuildProvider的Dll引用或者項目引用。然後添加一個XML檔案,并将擴充名改成.msg,然後定義如下一段XML。

然後在Web.config中添加如下一段配置以建立MessageBuildProvider和源檔案擴充名(.msg)之間的比對關系。

然後,你在任何該WebSite範圍類進行程式設計的時候,就可以利用VS的職能感覺感受到相應的代碼已經生成。

<a href="http://images.cnblogs.com/cnblogs_com/artech/Windows-Live-Writer/9d35b281914e_1275E/image_2.png"></a>

為什麼說“感受”得到代碼已經被成功生成呢?這是因為不象之前介紹的兩種代碼生成方式,會顯式地建立一個.cs或者.vb實體檔案,并自動添加到項目檔案。BuildProvider采用的是一種隐式代碼生成機制。不過你通過Go

to

definition菜單可以得到整個生成代碼的内容。如果你采用基于C#的WebSite,生成的代碼時如下所示。由于CodeDOM的語言無關性,你也可以将MessageBuildProvider用于基于VB.NET的ASP.NET應用。

<a href="http://images.cnblogs.com/cnblogs_com/artech/Windows-Live-Writer/9d35b281914e_1275E/image_4.png"></a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2010/11/06/builderprovider.html" target="_blank">原文連結</a>