簡介 Microsoft® .NET 框架介紹了幾個新功能,旨在簡化應用程序發布和解決 DLL Hell。最終用戶和開發人員都熟悉版本和發布問題,這些問題會伴隨著如今基于組件的系統一同出現。例如,每個最終用戶都在他們的機器上安裝了一個新的應用程序,沒料到已有應用程序神秘地停止了工作。多數開發人員花費時間使用 Regedit,努力保持所有必要的注冊項一致以便激活 COM 類。 .NET 框架中用于解決 DLL Hell 問題的設計原則和實現技術是建立在 Microsoft Windows® 2000 的基礎上的, Rick Anderson 所著的 The End of DLL Hell(英文)和 David D'Souza, BJ Whalen 及 Peter Wilson 所著的 Implementing Side-by-Side Component Sharing in Applications (Expanded) (英文)中都有說明。.NET 框架提供的許多功能都在這兩篇文章中有所描述,包括應用程序隔離和并行組件,用于建立在 .NET 平臺的應用程序。您將了解 .NET 平臺上提供的版本支持,它能使本地 Windows 應用程序更緊密地匯集。 本文介紹了匯編的概念,并描述 .NET 如何使用匯編來解決版本和發布問題。我們將特別討論匯編如何構建,如何命名以及編譯器和通用語言運行時如何使用匯編來記錄和加強應用程序片段間的版本依賴。我們也將討論應用程序和管理員如何能通過我們所稱的版本策略定制版本行為。 介紹并說明了匯編后,將展示幾個發布方案,以便使您對 .NET 框架中提供的各種打包和分發選項多少有一些了解。
版本 從客戶的角度,最常見的版本問題就是我們所說的 DLL Hell 問題。簡單地講, DLL Hell 是指當多個應用程序試圖共享一個公用組件(如某個動態連接庫(DLL)或某個組件對象模型(COM)類)時所引發的一系列問題。最典型的情況是,某個應用程序將要安裝一個新版本的共享組件,而該組件與機器上的現有版本不向后兼容。雖然剛安裝的應用程序運行正常,但原來依賴前一版本共享組件的應用程序也許已無法再工作。在某些情況下,問題的起因更加難以預料。比如,當用戶瀏覽某些 Web 站點時會同時下載某個 Microsoft ActiveX® 控件。如果下載該控件,它將替換機器上原有的任何版本的控件。如果機器上的某個應用程序恰好使用該控件,則很可能也會停止工作。 在許多情況下,用戶需要很長時間才會發現應用程序已停止工作。結果往往很難記起是何時的機器變化影響到了該應用程序。用戶可能會回憶起一周前安裝了一些東西,但安裝與目前看到的狀態并沒有任何明顯的關聯。 更糟的是,現在很少有診斷工具幫助用戶(或幫助他們的技術支持人員)確定有什么問題。 這些問題的原因是應用程序不同組件的版本信息沒有由系統記錄或加強。而且,系統為某個應用程序所做的改變會影響機器上的所有應用程序—現在建立完全從變化中隔離出來的應用程序并不容易。 很難建立一個隔離應用程序的一個原因是當前運行時環境只允許單獨版本組件或應用程序的安裝。這個限制意味著組件的編寫者必須以向后兼容的方式編寫他們的代碼,否則當他們安裝新組件的時候會有終止已有應用程序的風險。實際上,如果可能的話,編寫永遠向后兼容的代碼是非常難的。在 .NET 中,side by side 概念是版本問題的核心。"Side by side" 是在同一臺機器上同時運行不同版本的相同組件的能力。使用支持并列的組件,編程人員不必努力維護嚴格的向后兼容,因為不同的應用程序自由使用某個共享組件的不同版本。 發布和安裝 現在安裝應用程序是多步過程。一般,安裝一個應用程序包括復制許多軟件組件到磁盤,和在系統中進行一系列描述那些組件的注冊項。 注冊表中的項和磁盤上文件的分隔使復制應用程序和卸載他們非常困難。而且,在注冊表中完全描述某個 COM 類所需的許多項之間關系非常松散。這些項常常包括聯合類、接口、類型庫和 DCOM app ID 的項,不涉及任何放在注冊表文檔擴展或組件類別的項。要時常手工保持這些項的同步。 最后,需要該注冊足跡激活任何 COM 類。這極大地復雜了發布分布式應用程序的過程,因為必須到每個客戶端的機器進行適當的注冊項。 如今另一個共同問題是:對一個正在運行的應用程序進行更新是不現實的。這是 Web 應用程序最大的問題,Web 應用程序必須停止工作然后重啟動以更新應用程序使用的 COM 類。 這些問題主要由從組件自己分離傳來的組件描述引起的。換句話說,應用程序不是自描述的和獨立的。
.NET 框架必須提供以下基本的能力解決剛剛描述的問題: 應用程序必須是自描述的:自描述的應用程序去掉了對注冊表的依賴,能夠毫無影響的安裝和簡單的卸載和復制。
匯編是 .NET 框架用于解決剛描述的版本和發布問題的積木。匯編是類型和資源的發布單元。在許多方面匯編和現在的 DLL 相同。從本質上講,匯編是“邏輯 DLL”。 匯編是通過元數據調用清單自描述的。就像 .NET 使用元數據描述類型一樣,它也使用元數據描述包含類型的匯編。 匯編不僅僅于發布有關。例如,.NET 中的版本在匯編層完成 —沒有任何減少,就像一個模塊或類型的版本化。而且,匯編還用于在應用程序之間共享代碼。包含某個類型的匯編是該類型標志的一部分。 訪問安全系統的代碼在其許可模型的內核中使用匯編。匯編的編寫者在清單中記錄一組運行該代碼所需求的許可,然后管理員將許可授權給基于匯編的代碼,此匯編包含該代碼。 最后,匯編也是類型系統和運行時間系統的核心,在其中他們為類型和服務建立了一個可視的邊界作為解決引用類型的運行時間范圍。 匯編清單 清單明確包括以下有關匯編數據: 標識:一個匯編標識由三部分組成:名稱、版本號和選項文化。
圖 1. 以 IL 反匯編顯示的范例清單 匯編結構 到此為止,匯編主要以邏輯概念描述。本節通過描述他們如何在物理上體現幫助您使匯編更加具體。 通常,匯編由四個元素組成:匯編元數據(清單)、元數據描述類型、實現該類型的媒介語言 (IL) 代碼和一組資源。不是所有的這些都出現在每個匯編中。只有清單是嚴格需要的,但類型或資源需要給匯編一些重要的功能。 有幾個關于這四個元素能如何包裝的選項。例如,圖 2 表示包含整個匯編:清單、類型元數據、IL 代碼和資源。 圖 2. 包含所有匯編元素的 DLL 另一種情況,一個匯編的內容也許分割為多個文件。在圖 3 中,作者選擇將一些有用的代碼分離到一個不同的 DLL 中,并在它的原始文件中保留一個大的資源文件(這里是一個 JPEG 文件)。這樣做的一個原因就是優化代碼的下載。.NET 框架只在引用時才下載文件,所以如果匯編包含經常被訪問的代碼或資源,那么將他們分成單獨的文件將提高下載的效率。 圖 3. 匯編元素分割為多個文件 |
溫馨提示:喜歡本站的話,請收藏一下本站!