最近在看設計模式的一些東西,在講到builder模式中使用到了c#的反射機制,從網上找了寫資料,整理如下:
?
在C#中,我們要使用反射,首先要搞清楚以下命名空間中幾個類的關系:?
?System.Reflection命名空間
(1)??AppDomain:應用程序域,可以將其理解為一組程序集的邏輯容器
(2)??Assembly:程序集類
(3)??Module:模塊類
(4)??Type:使用反射得到類型信息的最核心的類
他們之間是一種從屬關系,也就是說,一個AppDomain可以包含N個Assembly,一個Assembly可以包含N個Module,而一個Module可以包含N個Type.?AppDomain這個類我們等下再來講解。我們先關注Assembly個類,在程序中,如果我們要動態加載一個程序集怎么辦呢?有幾種方式可以使用,分別是Load,LoadFrom和LoadWithPartialName三個Assembly的靜態方法.
???????先來講解Assembly.Load方法,該方法會有多個重載版本,其中一個就是提供程序集的詳細信息,即程序集的標識,包括程序集的名稱,版本,區域信息,公有密鑰標記,全部都是以一個字符串的形式提供,例如:"MyAssembly,Version=1.0.0.0,culture=zh-CN,PublicKeyToken=47887f89771bc57f”.
?????????????那么,使用Assembly.Load加載程序集的順序是怎樣的呢?首先它會去全局程序集緩存查找,然后到應用程序的根目錄查找,最后會到應用程序的私有路徑查找。
?????????????當然,如果你使用的是弱命名程序集,也即只給出程序集的名稱,那么這個時候,CLR將不會在程序集上應用任何安全或者部署策略,而且Load也不會到全局緩存程序集中查找程序集。
Assembly.Load("")的使用說明如下; ?
? 并不是命名空間。常用的是程序集名稱,也就是dll的名稱 ?
? ? 重載列表 ? ?
? 名稱 ? ? 說明 ? ? ?
? Assembly.Load ? (AssemblyName) ? ? 在給定程序集的 ? AssemblyName ? 的情況下,加載程序集。 ? ?
? 由 ? .NET ? Compact ? Framework ? 支持。?????
? Assembly.Load ? (Byte[]) ? ? 加載帶有基于通用對象文件格式 ? (COFF) ? 的圖像的程序集,該圖像包含已發出的程序集。將該程序集加載到調用方的域。 ? ? ?
? Assembly.Load ? (String) ? ? 通過給定程序集的長格式名稱加載程序集。?
? 由 ? .NET ? Compact ? Framework ? 支持。?????
? Assembly.Load ? (AssemblyName, ? Evidence) ? ? 在給定程序集的 ? AssemblyName ? 的情況下,加載程序集。使用提供的證據將該程序集加載到調用方的域中。 ? ? ?
? Assembly.Load ? (Byte[], ? Byte[]) ? ? 加載帶有基于通用對象文件格式 ? (COFF) ? 的圖像的程序集,該圖像包含已發出的程序集。 ? ? ?
? Assembly.Load ? (String, ? Evidence) ? ? 通過給定的程序集的顯示名稱來加載程序集,使用提供的證據將程序集加載到調用方的域中。
? Assembly.Load ? (Byte[], ? Byte[], ? Evidence) ? ? 加載帶有基于通用對象文件格式 ? (COFF) ? 的圖像的程序集,該圖像包含已發出的程序集。
?
關于反射Assembly.Load("程序集").CreateInstance("命名空間.類")
而不管在哪一層寫這段代碼其中的("程序集")讀取的實際是web層bin文件夾下的dll,也就是說你反射的類的程序集dll在web層的bin下必須有
注意CreateInstance()一定是命名空間.類名,否則創建的實例為空
Assembly.Load("程序集名")
Assembly.LoadFrom("程序集實際路徑"
http://space.itpub.net/12639172/viewspace-442007
最近看了一些關于C#反射的知識,估計也就最多達到使用API的程度,至于要深入了解,以現在的水平估計很難做到,所以下面此篇文章,以作為一個階段的總結。?
???????對于反射的總結,我想從以下幾個方面展開,首先是反射程序集,模塊,類的成員以及成員的一些信息;接下來就是動態調用類的成員方法;第三個方面就動態產生程序集,模塊和類以及類的成員。好了,現在就讓我們從反射各種信息開始吧?
???????在C#中,我們要使用反射,首先要搞清楚以下命名空間中幾個類的關系:?
????????????? System.Reflection命名空間?
(1)???AppDomain:應用程序域,可以將其理解為一組程序集的邏輯容器?
(2)???Assembly:程序集類?
(3)???Module:模塊類?
(4)???Type:使用反射得到類型信息的最核心的類?
他們之間是一種從屬關系,也就是說,一個AppDomain可以包含N個Assembly,一個Assembly可以包含N個Module,而一個Module可以包含N個Type.?
?????? AppDomain這個類我們等下再來講解。我們先關注Assembly個類?
????????在程序中,如果我們要動態加載一個程序集怎么辦呢?有幾種方式可以使用,分別是Load,LoadFrom和LoadWithPartialName三個Assembly的靜態方法.?
????????先來講解Assembly.Load方法,該方法會有多個重載版本,其中一個就是提供程序集的詳細信息,即程序集的標識,包括程序集的名稱,版本,區域信息,公有密鑰標記,全部都是以一個字符串的形式提供,例如:"MyAssembly,Version=1.0.0.0,culture=zh-CN,PublicKeyToken=47887f89771bc57f”.?
??????????????那么,使用Assembly.Load加載程序集的順序是怎樣的呢?首先它會去全局程序集緩存查找,然后到應用程序的根目錄查找,最后會到應用程序的私有路徑查找。?
??????????????當然,如果你使用的是弱命名程序集,也即只給出程序集的名稱,那么這個時候,CLR將不會在程序集上應用任何安全或者部署策略,而且Load也不會到全局緩存程序集中查找程序集。?
???????測試加載弱命名程序集的例子如下:?
(1)???新建一個控制臺應用程序的工程,同時勾選創建解決方案?
(2)???在解決方案中新建一個類庫的項目,隨便寫一個類和一個方法?
(3)???在控制臺項目中,首先不添加引用,直接在Main方法中添加如下代碼:?
Assembly?assembly =?Assembly.Load("MyAssembly");?
??????????????? ??if?(assembly !=?null)?
???????????????? ?{?
????????????????????????Console.WriteLine("加載成功");?
?????????????????? }?
???????執行程序,會拋出異常,說找不到該程序集。什么原因呢?因為我們使用的是弱命名程序集,Load方法不會去全局程序集緩存中查找,而該應用程序目錄下又沒有該程序集,所以程序找不到。這個時候,我們把程序稍微改一下,不用添加代碼,只需添加對MyAssembly的引用,重新運行程序,加載成功了。?
??????接下來,我們就要看看Load怎么加載強命名程序集了,這個步驟稍微有些復雜。還是剛才的項目,找到MyAssembly.dll程序集所在的目錄,一般在bin\Debug目錄下?
(1)生成密鑰對文件?
sn –k MyAssemblyKey.keys?
你也可以自己隨便起一個密鑰對文件名?
(2)生成公鑰文件
sn –p??MyAssemblyKey.keys?MyAssemblyPublicKey.PublicKey?
注:查看公鑰命令:sn –tp MyAssemblyPublicKey.PublicKey?
??
(3)創建強命名程序集。?
很簡單,只需要在聲明命名空間的那句代碼上加上如下特性:?
[assembly:AssemblyKeyFileAttribute(@”D:\Test\MyAssemblyKey.keys”)]?
??
(4)???編譯項目?
(5)???將程序集添加到程序集全局緩存?
gacutil –i MyAssembly.dll?
這個時候,轉到加載程序集的項目中,將Load方法中的參數改為”程序集名,Version=版本,culture=區域信息,PublicKeyToken=公鑰“,然后再去掉對程序集的引用,我們會發現,程序運行成功。表明Load到全局緩存區查找到了該程序集。?
???????使用Load方法加載程序集,特別是強命名程序集,能在程序集上應用安全和部署策略,推薦使用該方法動態加載程序集,至于LoadFrom和LoadWithPartialName,我們下次會做一些簡單的介紹,同時也希望有軟友能指出文中的錯誤或者遺漏的地方。下回見。
http://dev.firnow.com/course/1_web/webjs/200877/132108_2.html