熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> ASP編程 >> 正文

VB.NET中的動態代碼生成技巧

2013-11-15 12:53:04  來源: ASP編程 

  本文的討論也將著眼於這兩種情況首先是當程序員需要動態建立一個控件並將代碼附著於控件之上時例如你或許想創建一個鏈接列表但是不知道需要創建鏈接的數量或是鏈接中會出現什麼樣的數據第二種是當程序員需要定義代碼以反映出特殊需求的時候例如你或許要執行能反映用戶系統配置的代碼

  類似上述的情況當然不會每天都上演事實上它們只在非常情況下才出現然而作為程序員仍然要意識到NET為解決動態情形提供了方案有了正確的技巧你就可以寫出能靈活處理動態情況的應用程序了

  使用動態控件

  許多程序員總會遇到需要動態創建控件的時候我們所展示的例子中程序員向FlowLayoutPanel中添加了LinkLabels或許你可以個這樣的設置來記錄和保存常用的URL文件網絡地址或是其他資源所在位置的數值這一示例沒有真正保存鏈接但是你可以使用XML序列化功能來實現保存

  每次當用戶點擊Test按鈕時示例代碼就會動態創建一個新的LinkLabel控件真正的演示代碼並不復雜例一就展示了創建這類控件以及將控件放入FlowLayoutPanellstLabel中通常所需要做的一切

  例一向FlowLayoutPanel中添加新的鏈接
 Private Sub btnTest_Click()   
Handles btnTestClick   
 Create a link   
Dim NewLink As LinkLabel =  
New LinkLabel()   
 Add some properties to it   
NewLinkText = DateTimeNow   
ToLongTimeString()   
 Set the click event handler   
AddHandler NewLinkClick   
AddressOf NewLink_Click   
 Place the button on the form   
lstLinksControlsAdd(NewLink)   
End Sub

  如你所料該代碼開始的時候創建了一個新的LinkLabel並為其賦予了一些值這一示例使用的是當前時間你的代碼或許能夠對某一真實資源進行訪問

  請注意該代碼也向鏈接的Click事件中指定了一個處理程序你必須使用示例中的AddHandler技巧因為普通的Handles關鍵詞路徑不起作用一方面設計應用程序的時候你並不清楚控件的名稱即便你為控件指定了一個名稱你也不知道用戶要創建的控件數量所以我們沒有辦法清楚會有多少處理程序會被創建處理程序的代碼與控件代碼類似因此沒有必要創建多個處理程序用於這個示例的處理代碼見例二例二處理動態控件點擊事件
 Private Sub NewLink_Click( _   
ByVal sender As SystemObject ByVal e As SystemEventArgs)  
 Verify that you actually have a LinkLabel  
If Not senderGetType() Is GetType(LinkLabel) Then  
MessageBoxShow(Wrong control type provided!)  
Return  
End If  
 Convert the input sender to a Button  
Dim ThisLink As LinkLabel = sender 
 Show that we have the correct button  
MessageBoxShow(You created this link at:  + ThisLinkText)  
End Sub 

  你可能已經注意到例一中的事件處理器使用的是寬松代表——它沒有將ByVal發送器作為SystemObject也沒有將ByVal e作為SystemEventArgs作為參數因為它不需要這二者然而當你創建一個事件處理器來動態創建控件時通常你需要將ByVal發送器作為SystemObject參數這意味著將這兩者都包含其中

  有些程序員在創建事件處理器的時候會出現一個錯誤即沒有檢查傳入控件的類型發送器對象可能包含多選擇而如果未對事件處理器進行事件處理類型的設置那麼你就會面臨更多的選擇我們的示例代碼一開始就檢查了傳入控件對象的類型這樣以來發送器就不會像下面所展示的代碼一樣
 Private Sub btnTest_Click() Handles btnTestClick   
 Create a link  
Dim NewButton As Button = New Button()  
 Add some properties to it  
NewButtonText = DateTimeNowToLongTimeString()  
 Set the click event handler  
AddHandler NewButtonClick AddressOf NewLink_Click  
 Place the button on the form  
lstLinksControlsAdd(NewButton)  
End Sub 

  此代碼在FlowLayoutPanel中創建了一個按鈕大多數情況下這都能正常運行除非事件處理器不按照按鈕所示的進行操作如果你打算服務多個控件類型那麼每個控件類型都需要一個獨特的處理你可以使用多事件處理器或者為某些類型提供選擇標准

  NewLink_Click()事件處理器照常將傳入發送器轉換成指定類型在這個示例中則是LinkLabel該代碼可以訪問LinkLabel屬性並能用其他方式進行互動在我們的示例中只顯示了一個能在創建鏈接的時候告知我們的對話框

  使用動態代碼

  在運行時創建一個控件是在無法確定應用程序功能的時候采取的一種策略但是動態創建控件並不適用於所有的情況有些時候你必須建立可執行代碼雖然你的應用程序運行的目的是補償不同極其之間的配置不同用戶的需求不同的環境需求或是其他要求當應用程序所運行的電腦不存在控件那麼通常是需要創建動態代碼的

  幸運的是NET為我們提供了一系列動態代碼選項例如你可以創建一個可執行的能獨立運行的程序或是可以想運行中的程序加載一個DLL然後再執行當你需要演示一個外部任務的時候可以使用選擇可執行如運行一種腳本——該DLL選項最適合擴大現有的應用程序功能

  你可以運行來自文件或內存的動態代碼當你需要不止一次地運行代碼時可以使用文件對代碼的檢查可以再次運行外部文件而不需要對其進行二次編譯當你需要多次演示任務的時候如一個安裝請求那可以使用內存圖像

  當然我們也可以更改源代碼例如你可以使用字符串來建立需要在應用程序中直接使用的代碼如果你需要代碼具有高度靈活性且代碼本身不是很長時這一方法的優勢就非常顯著也可以從文件裡建立代碼就如同VS一樣這一方法最適用於相對穩定且不需要復雜編碼的需求第三種選擇是使用Documentation Object Model來創建代碼並將其作為CodeDom樹型結構的一個系列該樹型結構包括了CodeCormpileUnits這就像是用DOM模式創建了一個XML文件

  使用動態創建代碼的最好方式是用示例來檢查一下例三展示了一個基本Hello World示例該示例用源代碼直接創建了代碼因此你可以看到整個運行以及生成一個外部可執行文件的過程

  例三動態編碼示例
 Private Sub btnTest_Click() Handles btnTestClick   
 Create a compiler  
Dim Comp As VBCodeProvider = New VBCodeProvider()  
 Define the parameters for the code you want to compile  
Dim Parms As CompilerParameters = New CompilerParameters)  
 
 We do want to create an executable rather than a DLL  
ParmsGenerateExecutable = True 
 The compiler will create an output assembly called Output  
ParmsOutputAssembly = Output 
 The compiler wont treat warnings as errors  
ParmsTreatWarningsAsErrors = False 
 Add any assembly you want to reference  
ParmsReferencedAssembliesAdd(SystemWindowsFormsdll)  
 
 Define the code you want to run  
 
Dim SampleCode As StringBuilder = New StringBuilder()  
 
SampleCodeAppend(Imports SystemWindowsForms + vbCrLf)  
 
SampleCodeAppend(Module TestAssembly + vbCrLf)  
 
SampleCodeAppend(Sub Main() + vbCrLf)  
 
SampleCodeAppend(MessageBoxShow( + Chr() + _  
Dynamically Created Code! + _Chr() + ) + vbCrLf)  
SampleCodeAppend(End Sub + vbCrLf)  
SampleCodeAppend(End Module + vbCrLf)  
 Define the code to run  
Dim Executable As CompilerResults = _ 
CompCompileAssemblyFromSource(Parms SampleCodeToString())  
 Display error messages if there are any  
If ExecutableErrorsHasErrors Then  
For Each Item As CompilerError In ExecutableErrors  
MessageBoxShow(ItemErrorText)  
Next  
Else  
 If there arent any error messages start the  
 executable  
ProcessStart(Output)  
End If  
End Sub 

  一開始你創建了一個使用VBCodeProvider的編譯器Comp舊一點的NET版本使用的是不同的方法但是這裡所講的是微軟推薦的一個新方法

  為了使用編譯器你必須創建能描述應用程序的參數這些參數類似於VS中你創建的參數只是現在你可以對它們進行定義該代碼一開始就將GenerateExecutable設置為True這意味著你需要的是一個EXE文件而不是DLL

  ParmsOutputAssembly屬性包含了輸出文件的名稱你只需要在想創建文件時提供這一信息即可而不需要生成可執行內存了如果你ixiang生成可執行文件的內存版本可以將ParmGenerateInMemory屬性設置為True

  使用ParmTreatWarningsAsErrors屬性來確定如何處理警告信息默認的設置會使其為錯誤這意味著你的應用程序可能無法對其進行編譯大多數程序員使用默認設置盡管他們開發了程序但是在開發完成的程序中卻將其設置為False

  大多數應用程序需要外部DLL以正常運行當然你不能創建任意的沒有引用外部DLL的Windows表單程序通常你要使用Reference文件夾來完成這一任務不過當你動態創建代碼的時候可以依賴於ParmsReferencedAssemblies屬性如下所示只需添加你要的DLL即可

  現在你已經定義了項目接下來需要為其創建源代碼如前文所述你可以依賴於一個外部文件或DOM模式然後該示例創建了代碼因此你可以看到整個過程下面是代碼的原始形式
 Imports SystemWindowsForms   
Module TestAssembly  
Sub Main()  
MessageBoxShow(Dynamically Created Code!)  
End Sub  
End Module 

  這個簡單的例子顯示了一個對話框注意vbCrLf的使用如果你不使用這一方法那編譯器會發送給你一個錯誤信息vbCrLf條目在該代碼中所起的作用與在程序代碼中的作用相同只是添加的方式不一樣

  從這一點老說你最後會用CompCompileAsseblyFromSource()方法編譯代碼當使用DOM模式和文件的時候可以使用這一方法而在所有三種情況中編譯器用參數和源代碼創建了你請求的輸出該運算的輸出出現在Executable中是CompilerResults類型

  編譯的失敗次數多於程序員的預計無論你是在哪裡使用動態編碼技巧你必須假設會出現失敗的情況以及處理失敗的方案在本例中代碼尋找的是錯誤並在編譯失敗時將其展示在了信息框中否則代碼會依賴於ProcessStart()方法來啟用可執行文件

  底線

  動態編碼技巧並不是萬能鑰匙當你為開發問題找到了好的靜態解決方案時當然也可以使用但是在我們所列出的情況中沒有可行的靜態方案因此要選擇動態編碼技巧大多數情況下要用動態編碼技巧解決以下問題

  ◆ 用戶的環境會以不可預見的方式更改時

  ◆ 無法控制用戶電腦的安裝

  ◆ 用戶或應用程序都添加了你要用控件執行的數據要素

  ◆ 應用程序必須執行很早以前的安裝任務且這些任務與電腦環境網絡或其他不確定因素聯系緊密時

  ◆ 應用程序要執行了處理級別的任務且這些任務取決於機器連接或其他狀況

  顯然還有其他一些情況能使用動態編碼技巧最重要的是記住但凡有不可預知的情況下要考慮使用動態編碼技巧通常在編碼環境中出現了靜態代碼無法處理的情況時我們就可以使用動態編碼技巧


From:http://tw.wingwit.com/Article/program/ASP/201311/21812.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.