基于組件的.NET軟件開發(4)
2024-07-10 13:03:50
供稿:網友
設計示例用到的組件
創建兩個vb.net類庫工程:dynamiccomponent和vbdynamiccomponent2,分別創建兩個窗體vbform1和vbform2(如圖6圖7所示),前者放在dynamiccomponent工程中,后者放在vbdynamiccomponent2工程中。
分別編譯生成兩個dll文件:dynamiccomponent.dll和vbdynamiccomponent2.dll。
接著,我們創建一個windows應用程序vbtestdynamiccomponent用于測試我們的組件裝配技術。
讀取xml配置文件
在測試程序啟動時,它從xml配置文件中讀取信息,我們看到,相關信息可以分為兩類:一類是要裝入的dll文件清單,另一類是需要裝入的類名。這兩者是一一對應的,所以,我們可以創建兩個arraylist,一個用于存放文件名,一個用于存放類名,然后,用一個類mycomponentlist把這兩個arraylist給封裝起來,外部使用者只需給出索引,就可以馬上同時得到文件名與類名。
類的接口設計如下:
圖 9 用于實現動態裝入組件的類
參見圖9,只要給mycomponentlist類的對象指定一個xml配置文件名,再調用beginread(),調用者就可以通過索引(0,1,2……)來獲取文件名和類名。
讀取xml格式數據可以使用.net framework所提供的xmltextreader類。完整代碼如下:
'從xml配置文件中讀取組件的類名與文件名
imports system.collections.specialized
imports system.windows.forms
public class mycomponentlist
private xmlreader as xml.xmltextreader
private _filename as string 'xml配置文件名
private _componentfilename as string '組件庫文件名
private _componentname as string '組件庫中的類名
private componentnames as arraylist '存放配置文件中列出的所有組件類名
private componentfiles as arraylist '存放配置文件中列出的所有組件庫名
'在構造函數中創建相關對象
public sub new(byval filename as string)
_filename = filename
_componentfilename = ""
_componentname = ""
componentnames = new arraylist()
componentfiles = new arraylist()
xmlreader = new xml.xmltextreader(filename)
end sub
'xml配置文件名
public property filename() as string
get
return _filename
end get
set(byval value as string)
'文件名空則應拋出異常.
_filename = value
end set
end property
'讀取組件庫
public sub beginread()
dim b1, b2 as boolean
b1 = false
b2 = false
'以下循環讀入文件,使用標記b1和b2來實現“組件庫文件ß à組件名”的配對,
'并分別存入對應的兩個arraylist中(componentfiles ß àcomponentnames)
while xmlreader.read
if xmlreader.name = "component" then
xmlreader.movetofirstattribute()
if xmlreader.name = "componentname" then
_componentname = xmlreader.value
b1 = true
end if
if xmlreader.name = "componentfilename" then
_componentfilename = xmlreader.value
b2 = true
end if
while xmlreader.movetonextattribute()
if xmlreader.name = "componentname" then
_componentname = xmlreader.value()
b1 = true
end if
if xmlreader.name = "componentfilename" then
_componentfilename = xmlreader.value()
b2 = true
end if
if b1 and b2 then
componentnames.add(_componentname)
componentfiles.add(_componentfilename)
b1 = false
b2 = false
end if
end while
end if
end while
end sub
'取出指定索引的文件名(即組件庫文件名)
public function getfilename(byval index as integer) as string
return componentfiles.item(index)
end function
'取出指定索引的類名(即組件名)
public function getclassname(byval index as integer) as string
return componentnames.item(index)
end function
end class
這些代碼非常清晰,就不多廢話了。
動態創建對象
知道了需要裝入的組件,下一步就是如何創建對象了,這需要用到system.reflection中的類。
同樣地,我們也設計一個類loadcomponent用于封裝創建對象的功能:
圖 10 完成創建組件對象的類
這個類的使用非常簡單,給定一個dll文件名,loadcomponentlibrary()函數用于將此dll裝入內存,之后,便可使用loadclass創建指定類的對象。
現在我們來逐步分析一下這個類。
(1)裝入組件庫:
首先必須了解,在.net中把可以復用的組件庫稱為“assembly”,一般譯為“程序集”(在上文中所提到的組件庫,其實就是指程序集),大多數情況下,每個.net dll都是一個程序集。而可以復用的類就放在程序集中。為此,要動態根據類的名字來創建對象,就必須首先把程序集裝入內存。在.net中,可以通過反射技術來實現這一點。示例代碼如下:
private mydll as system.reflection.assembly
public function loadcomponentlibrary(byval componentfilename as string) as boolean
'裝入指定的組件代碼庫
'成功返回true
try
mydll = system.reflection.assembly.loadfrom(componentfilename)
if mydll is nothing then
messagebox.show("can't load library")
return false
end if
catch errobj as systemexception
messagebox.show(errobj.message)
return false
end try
return true
end function
(2)創建對象:
一旦程序集被裝入內存,我們就可以根據類名字串來創建對象了,如下所示:
private obj as object
public function loadclass(byval classname as string) as object
if mydll is nothing then
return nothing
end if
try
obj = mydll.createinstance(classname)
catch errobj as systemexception
messagebox.show(errobj.message)
return nothing
end try
return obj
end function
有了loadcomponent類,我們以后要做的事就簡單多了。
本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。