官术网_书友最值得收藏!

1.3 程序集

程序集是.NET Framework應用程序的構造塊,它構成了部署、版本控制、重復使用、激活范圍控制和安全權限的基本單元。本節將詳細介紹程序集的相關內容,如程序集的內容、可執行功能以及程序集清單等。

1.3.1 程序集概述

程序集是為協同工作而生成的類型和資源的集合,這些類型和資源構成了一個邏輯功能單元。它向CLR提供了解類型實現所需要的信息,對于CLR來說,類型不存在于程序集上下文之外。

程序集是擴展名為.dll或.exe的文件,它是.NET Framework編程的基本組成部分,每個程序集只能有一個入口點(即DllMain、WinMain或Main)。使用程序集可以執行以下功能:

□ 包含CLR執行的代碼。如果可移植可執行(PE)文件沒有相關聯的程序集清單,則將不執行該文件中的Microsoft中間語言(MSIL)代碼。

□ 程序集形成安全邊界。程序集就是在其中請求和授予權限的單元。

□ 程序集形成類型邊界。每一類型的標識均包括該類型所駐留的程序集名稱,在一個程序集范圍內加載的MyType類型不同于在其他程序集范圍內加載的MyType類型。

□ 程序集形成引用范圍邊界。程序集的清單包含用于解析類型和滿足資源請求的程序集元數據,它指定在該程序集之外公開的類型和資源。

□ 程序集形成版本邊界。程序集是公共語言運行時中最小的可版本化單元,同一程序集中的所有類型和資源均會被版本化為一個單元。

□ 程序集形成部署單元。當一個應用程序啟動時,只有該應用程序最初調用的程序集必須存在。

□ 程序集是支持并行執行的單元。

程序集可以是靜態的,也可以是動態的。靜態程序集存儲在磁盤上的可移植可執行(PE)文件中,它可以包括.NET Framework類型(接口和類)以及該程序集的資源(如位圖、JPEG文件和資源文件等)。

動態程序集直接從內存運行并且在執行前不存儲到磁盤上,但是在執行動態程序集后可以將它們保存到磁盤上,開發人員可以使用.NET Framework來創建動態程序集。

程序集創建時有多種方法,常用方法有3種。如下所示:

□ 使用用來創建.dll或.exe文件的開發工具,例如Visual Studio 2010。

□ 使用在.NET Framework SDK中提供的工具來創建帶有在其他開發環境中創建的模塊的程序集。

□ 使用CLR API(例如Reflection.Emit)來創建動態程序集。

1.3.2 程序集優點

程序集旨在簡化應用程序部署并解決在基于組件的應用程序中可能出現的版本控制問題。目前,Win32應用程序存在兩類版本控制問題:

□ 版本控制規則不能在應用程序的各段之間表達,并且不能由操作系統強制實施。目前的辦法依賴于向后兼容,而這通常很難保證。

□ 沒有辦法在創建到一起的多套組件集與運行時提供的那套組件之間保持一致。

上述兩類版本控制問題結合在一起產生了DLL沖突,在這些沖突中安裝一個應用程序可能會無意間破壞現有的應用程序,因為所安裝的某個軟件組件或DLL與以前的版本不完全向后兼容。

為了解決版本控制問題以及導致的DLL沖突的其余問題,運行時使用程序集來執行以下功能:

□ 使開發人員能夠指定不同軟件組件之間的版本規則。

□ 提供強制實施版本控制規則的結構。

□ 提供允許同時運行多個版本的軟件組件(稱作并行執行)的基本結構。

通過在.NET Framework中使用程序集,可以使許多開發問題得到解決,因為程序集不依賴于注冊表項的自述組件,所以程序集使無相互影響的應用程序安裝成為可能,程序集還使應用程序的卸載和復制得以簡化。

1.3.3 程序集內容

一般情況下,靜態程序集由4個元素組成:程序集清單、類型元數據、實現這些類型的Microsoft中間語言(MSIL)代碼和資源集。在這4種元素中,程序集清單是必需的,但是它也需要類型或資源來向程序集提供任何有意義的功能。

程序中的元素分組有幾種方法,開發人員可以將所有元素分組到單個物理文件中,或者可以將一個程序集的元素包含在幾個文件中,這些文件可能是編譯代碼的模塊或應用程序所需的其他文件,如圖1-3和圖1-4分別顯示了單文件程序集結構圖和多文件程序集結構圖。

圖1-3 單文件程序集的結構圖

圖1-4 多文件程序集的結構圖

在圖1-4中的3個文件屬于一個程序集,對于文件系統而言,它們是獨立的文件,但是Until.net被編譯為一個模塊,它不包含任何程序集信息。當創建了程序集后,該程序集清單被添加到MyAssembly.dll,指示程序集與Until.net模塊和Graphic.hmp的關系。

1.3.4 程序集清單

每一個程序集,無論是靜態的還是動態的,都包含描述該程序集中各元素彼此如何關聯的數據集合,程序集清單就包含這些程序集元數據。程序集清單包含指定該程序集的版本要求和安全標識所需的所有元數據,以及定義該程序集的范圍和解析對資源和類的引用所需的全部元數據。

程序集清單可以存儲在具有Microsoft中間語言(MSIL)代碼的PE文件(.exe或.dll)中,也可以存儲在只包含程序集清單信息的獨立PE文件中。圖1-5和圖1-6根據程序集的類型分別顯示了清單的不同存儲方法。

圖1-5 單文件程序集的存儲方法

圖1-6 多文件程序集的存儲方法

從圖1-5中可以看出,對于一個關聯文件的程序集,該清單將被合并到PE文件中以構成單文件程序集。相關人員可以創建獨立的清單文件,或清單被合并到同一多文件程序集中某一PE文件的多文件程序集。

每一個程序集的清單都執行以下功能:

□ 枚舉構成該程序集文件。

□ 控制對該程序集的類型和資源的引用如何映射到包含其聲明和實現的文件。

□ 枚舉該程序集所依賴的其他程序集。

□ 在程序集的使用者和程序集的實現詳細信息的使用者之間提供一定程序的間接性。

□ 呈現程序集自述。

程序集清單包含了多項內容,如表1-1列出了清單中所包含的信息,其中前4項(程序集名稱、版本號、區域性和強名稱信息)內容構成了程序集的標識。

表1-1 程序集清單信息

1.3.5 全局程序集緩存

全局程序集緩存中存儲了專門指定給由計算機中若干應用程序共享的程序集,安裝有CLR的每臺計算機都具有稱為全局程序集緩存的計算機范圍內的代碼緩存。

應當僅在需要時才將程序集安裝到全局程序集緩存中以進行共享。一般原則是:程序集依賴項保持專用,并在應用程序目錄中定位程序集,除非明確要求共享程序集。另外,不必為了使COM互操作或非托管代碼可以訪問程序集而將程序集安裝到全局程序集緩存。

將程序集部署到全局程序集緩存中的方法有兩種:

□ 使用專用于全局程序集緩存的安裝程序,這種方法是將程序集安裝到全局程序集緩存的首選方法。

□ 使用Windows軟件開發包(SKD)提供的名為全局程序集緩存工具的開發工具。

提示

在部署方案中,應該使用Windows Installer 2.0將程序集安裝到全局程序緩存中,相關人員一般只在開發方案中使用全局程序集緩存工具,這是因為它不提供使用Windows Installer時可以提供的程序集引用計數功能和其他功能。

管理員通常使用訪問控制列表(ACL)來保護systemroot目錄,以控制寫入和執行訪問。因為全局程序集緩存安裝在systemroot目錄的子目錄中,它繼承了該目錄的ACL,建議只允許具有管理員權限的用戶從全局程序集緩存中刪除文件。

在全局程序集緩存中部署的程序集必須具有強名稱,將一個程序集添加到全局程序集緩存時必須對構成該程序集的所有文件執行完整性檢查,緩存執行這些完整性檢查以確保程序集未被篡改。

強名稱是由程序集的標識加上公鑰和數字簽名組成的,通過簽發具有強名稱的程序集可以確保名稱的全局唯一性。強名稱還需要特別滿足以下要求:

□ 強名稱依賴于唯一的密鑰對來確保名稱的唯一性。

□ 強名稱保護程序集的版本沿襲。

□ 強名稱提供可靠的完整性檢查。

1.3.6 程序集安全注意事項

生成程序集時可以指定該程序集運行所需的一組權限,是否將特定的權限授予程序集是基于證據的。使用證據有兩種不同的方式,第一種是將輸入證據與加載程序所收集的證據合并,以創建用于策略決策的最終證據集,這種方式的方法包括Assembly.load、Assembly.LoadFrom和Activator.CreateInstance。第二種方式是原封不動地使用輸入證據作為用于策略決策的最終證據集,使用這種語義的方法包括Assembly.Load(byte[])和AppDomain.DefineDynamicAssembly()。

通過在將運行程序集的計算機上設置安全策略,相關人員可以授予一些可選的權限。如果希望代碼可以處理所有潛在的安全異常,可以執行以下兩種操作:

□ 為代碼必須具有的所有權限插入權限請求,并預先處理在未授予權限時發生的加載時錯誤。

□ 不要使用權限請求來獲取代碼可能需要的權限,但一定要準備處理在未授予權限時發生的安全異常。

可以使用兩種不同但是相互補充的方式對程序集進行簽名,使用強名稱或使用.NET Framework 1.0和1.1版本中的Signcode.exe或.NET Framework更高版本中的SignTool.exe。

使用強名稱對程序集進行簽名將向包含程序集清單的文件添加公鑰加密。強名稱簽名幫助驗證名稱的唯一性,避免名稱欺騙,并且在解析引用時向調用方法提供某標識。但是,任何新人級別都不會與一個強名稱關聯,這樣Signcode.exe和SignTool.exe就變得十分重要。這兩個簽名工具要求發行者向第三方證書頒發機構證實其標識并獲取證書,然后此證書將嵌入到文件中,并且管理員能夠使用該證書來決定是否相信這些代碼的真實性。

相關人員可以將強名稱和使用Signcode.exe或SignTool.exe創建的數字簽名一起提供給程序集,或者可以單獨使用其中之一,這兩個簽名工具一次只能對一個文件進行簽名,對于多文件程序集,可以對包含程序集清單的文件進行簽名。強名稱存儲在包含程序集清單的文件中,但使用Signcode.exe或SignTool.exe創建的簽名存儲在該程序集清單所在的可遷移可執行(PE)文件中保留的槽中。

強名稱和使用Signcode.exe或SignTool.exe進行簽名確保了完整性,它們和其他相關技術共同作用可以確保程序集沒有做過任何方式的改動,因此相關人員可以將代碼訪問安全策略建立在這兩種形式的程序集證據基礎上。

1.3.7 程序集版本控制

本節所介紹的程序集版本控制,僅對具有強名稱的程序集進行版本控制。每一個程序集都使用兩種截然不同的方法來表示版本信息。

1. 程序集的版本號

程序集的版本號與程序集名稱及區域性信息都是程序集標識的組成部分。每一個程序集都有一個版本號作為其標識的一部分,因此,如果兩個程序集具有不同的版本號,運行時就會將它們視作不同的程序集。此版本號實際表示為具有以下格式的4部分號碼:

<主版本>.<次版本>.<生成號>.<修訂號>

例如,版本1.5.1254.0中1表示主版本,5表示次版本,1254表示生成號,而0表示修訂號。

2. 信息性版本

信息性版本是一個字符串,表示僅為提醒的目的而包括的附加版本信息。

使用CLR的程序集的所有版本控制都在程序集級別上進行,一個程序集的特定版本和依賴程序集的版本在該程序集的清單中記錄下來,除非被配置文件中的顯式版本策略重寫,否則運行時的默認版本策略是應用程序只與它們生成和測試時所用的程序集版本一起運行。CLR主要通過4步解析程序集的綁定請求:

(1)檢查原程序集引用,以確定該程序集的版本是否被綁定。

(2)檢查所有適用的配置文件(應用程序配置文件、發行者策略文件和計算機的管理員配置文件)以應用版本策略。

(3)通過原程序集引用和配置文件中指定的任何重定向來確定正確的程序集,并且確定應綁定到調用程序集的版本。

(4)檢查全局程序集緩存和在配置文件中指定的基本代碼,然后使用在運行時如何定位程序集中解釋的探測規則檢查該應用程序的目錄和子目錄。

主站蜘蛛池模板: 安丘市| 孝昌县| 收藏| 安吉县| 石门县| 绥中县| 九江县| 肇庆市| 甘洛县| 长宁县| 泰州市| 高青县| 潞城市| 历史| 洛南县| 盐源县| 南召县| 克拉玛依市| 鄱阳县| 额敏县| 普兰店市| 内乡县| 会理县| 鹤山市| 富宁县| 嘉义县| 拜泉县| 甘泉县| 朝阳区| 德令哈市| 杭锦后旗| 元朗区| 杂多县| 大厂| 大竹县| 昌邑市| 策勒县| 林西县| 黄大仙区| 新平| 龙里县|