反射 5 CLR 執行時探測程式集引用的步驟

2021-09-08 16:05:42 字數 4565 閱讀 4541

l開始繫結

當執行時嘗試解析對另乙個程式集的引用時,就開始進行定位並繫結到程式集的程序。

該引用可以是靜態的,也可以是動態的。無論引用是對靜態程式集的引用還是對動態程式集的引用,執行時均使用相同的解析過程。

a)靜態引用:在生成時,編譯器在程式集清單的元資料中記錄靜態引用。

b)動態引用:由於呼叫各種方法而動態構造的,載入方法詳細介紹請參見《(7)動態程式集載入load()》 。l

執行時使用以下步驟來【解析】程式集引用:第1

步:檢查配置檔案,確定版本

可以基於三個

xml

檔案在不同的級別下配置程式集繫結行為 :

a)應用程式配置檔案,可用於啟用安全模式。

b)發行者策略檔案,決定公升級繫結的新版本。

c)計算機配置檔案,決定繫結的最終版本。

這些檔案使用相同的語法,並且給特定程式集提供諸如繫結重定向、**位置以及繫結模式等資訊。eg:

(詳細語法請參見 《(4)繫結程式集配置策略》)

……" />

……1.

應用程式配置檔案

第一,在應用程式配置檔案中,公共語言執行時檢查覆蓋呼叫程式集清單中儲存的版本資訊的資訊。

應用程式配置檔案可以隨應用程式一起部署,但它並不是應用程式執行所必需的。

a)對於客戶端可執行檔案,應用程式配置檔案與應用程式可執行檔案位於同乙個目錄中,並且兩者具有相同的基檔名,但應用程式配置檔案的擴充套件名為

.config。b)

在基於瀏覽器的方案中,

html

檔案必須使用

元素顯式指向該配置檔案。

2.發行者策略檔案

(必須安裝在全域性程式集快取)

第二,執行時檢查發行者策略檔案(如果存在的話)。發行者策略檔案是由元件發行者作為共享元件的修正或更新分發的,即針對的是放入全域性程式集快取

(gac)

中的程式集。

這些檔案包含共享元件發行者發布的相容性資訊,這些資訊將程式集引用指向新版本,影響使用某個共享元件的所有應用程式。

發行者策略配置檔案覆蓋來自應用程式的版本資訊(即,來自於程式集清單或應用程式配置檔案)。

與應用程式配置檔案和計算機配置檔案不同,發行者策略檔案包含在其自己的程式集中,該程式集必須安裝在全域性程式集快取中。

(al.exe + gacutil.exe)

----------

安全模式

安全模式由

元素決定,該元素僅位於應用程式配置檔案中。

安全模式指定是否應該從繫結過程中移除發行者策略配置資訊。

通常,發行者策略檔案是作為

service pack

或程式更新的一部分顯式安裝的。

如果公升級的共享元件有任何問題,則可以使用安全模式忽略發行者策略檔案中的覆蓋。(預設為

yes)

a)整個應用程式設定安全模式:設定

,並且置於

元素內不包含依賴程式集元素。

b)特定的程式集設定安全模式:設定

並放置在

元素中,使用

元素指定要影響哪些程式集。

3.第三,計算機配置檔案(管理員策略檔案)

執行時檢查計算機配置檔案

machine.config

位於本地計算機上安裝【執行時】的根目錄的

config

子目錄中。

計算機配置檔案中的設定優先於所有其他配置設定,確定的版本是最終版本,並且不能被覆蓋。

machine.config

檔案中指定的覆蓋影響所有的應用程式。 第

2 步:檢查已經載入的程式集

在.net framework 2.0

以後比如

assembly.load

方法有快取,第一次載入目標程式集的失敗或者成功的狀態都會被快取,這樣在你下一次載入目標程式集時會直接從快取裡取目標程式集的內容和狀態。

當失敗後我們可能想要再載入一次或者載入多次直到成功為止,這時需要在

中加入如下配置資訊來禁用快取:

注意:reflectiononlyload()\reflectiononlyloadfrom()

只反射載入不會使用快取。第3

步:檢查全域性程式集快取

如果被引用的程式集是強命名的(換句話說,

assemblyref

包括了非空的公鑰或公鑰標記),那麼接下來就會在

gac中查詢這個程式集。否則,由於弱名稱程式集不能安裝在

gac中,就會跳過這一步。第4

步:通過基本**或探測定位程式集

在使用呼叫程式集的引用中的資訊和配置檔案中的資訊確定了正確的程式集【版本】之後,並且在公共語言執行時在全域性程式集快取中進行檢查(僅檢查具有強名稱的程式集)之後,公共語言執行時就會嘗試【查詢】該程式集。

定位程式集的過程包含以下步驟:

1)如果在配置檔案中找到對應的

元素,則執行時會檢查指定的位置。

配置檔案的

codebase

元素實際標記了乙個

url。這個

url可引用使用者機器上的任何目錄,也可以引用乙個

web位址。如果引用的是

web位址,

clr下的乙個子目錄)。將來進行引用時,

clrurl

處的檔案的時間戳進行比對。如果

url處的檔案具有較新的時間戳,

clrclr

如果找到匹配的程式集,則會使用該程式集,並且不會進行探測。

如果codebase

指定的可執行體與這個引用不匹配,會認為搜尋是失敗的,不會進行程式集載入。

2)沒有

元素則執行時使用指定的規則探測引用的程式集。

l通過探測定位程式集

如果應用程式配置檔案中沒有

元素,則執行時使用以下四個條件來探測程式集:

1.應用程式基,它是指向應用程式位置的

url(即指向應用程式所在的目錄)。

a)對於可執行體而言,它是包括

exe檔案的目錄。

b)對於

web應用程式而言,

是由web

伺服器定義的應用程式根目錄。

2.區域性,它是被引用的程式集的區域性特性。

3.名稱,它是被引用的程式集的名稱。

4.元素的

privatepath

特性,這是根位置下使用者定義的子目錄列表(必須是應用程式根目錄的子目錄)。

---------

探測應用程式基和區域性目錄

執行時始終在應用程式基中開始探測,應用程式基可以是乙個

url,也可以是計算機上的應用程式根目錄。

如果在應用程式基中沒有找到引用的程式集,並且未提供區域性資訊,則執行時使用程式集名稱搜尋任何子目錄。

探測的目錄包括:a)[

應用程式基

] / [

程式集名稱

].dll

b)[應用程式基

] / [

程式集名稱

] / [

程式集名稱

].dll

如果指定了引用的程式集的區域性資訊,則只探測以下目錄:a)[

應用程式基

] / [

區域性] / [

程式集名稱

].dll

b)[應用程式基

] / [

區域性] / [

程式集名稱

] / [

程式集名稱

].dll

---------

使用privatepath

特性進行探測

然後,執行時還探測使用

元素的privatepath

特性指定的目錄。探測的目錄包括:a)[

應用程式基

] / [bin

路徑] / [

程式集名稱

].dll

b)[應用程式基

] / [bin

路徑] / [

程式集名稱

] / [

程式集名稱

].dll

如果包含區域性,則探測以下目錄:a)[

應用程式基

] / [bin

路徑] / [

區域性] / [

程式集名稱

].dll

b)[應用程式基

] / [bin

路徑] / [

區域性] / [

程式集名稱

] / [

程式集名稱

].dll

與應用區別請參見: 《(4)繫結程式集配置策略》 

《反射機制》系列:

(1)程式集基礎知識

(2)強名稱程式集與數字證書

(3)程式集載入 assembly類

(4)繫結程式集配置策略

(5)clr 執行時探測程式集引用的步驟

(6)程式集載入上下文

(7)動態程式集載入load()

(8)程式集反射 type 類

(9)程式集的載入和反射

參考資源:

引導程式搜尋程式集

執行時如何定位程式集

反射 5 CLR 執行時探測程式集引用的步驟

l開始繫結 當執行時嘗試解析對另乙個程式集的引用時,就開始進行定位並繫結到程式集的程序。該引用可以是靜態的,也可以是動態的。無論引用是對靜態程式集的引用還是對動態程式集的引用,執行時均使用相同的解析過程。a 靜態引用 在生成時,編譯器在程式集清單的元資料中記錄靜態引用。b 動態引用 由於呼叫各種方法...

堆疊溢位的執行時探測(二)

3.技術 3.1 gnu lib c glibc 中的堆管理 c語言沒有提供如動態記憶體管理 字串操作 輸入輸出等內建功能,而是把這些功能定義在乙個標準庫中,當使用者使用的時候會被編譯和鏈結。gnu c庫就是這一乙個庫,定義了iso c標準中的所有庫函式,以及posix 可移植作業系統介面 和gnu...

反射獲取執行時類的結構

屬性 1.getfields 獲取當前執行時類及其父類中宣告為public訪問許可權的屬性 2.getdeclaredfields 獲取當前執行時類中宣告的所有屬性。不包含父類中宣告的屬性 4.getmodifiers 許可權修飾符 5.gettype 資料型別 6.getname 變數名 獲取執行...