本文節選自《.NET程序員面試指南》一書
在實際工作中,版本策略被使用得比較多,本節將借 助分析這個面試題來簡要介紹程序集的版本策略和配置方法。
所涉及到的知識點
版本策略 的基本原理
程序集版本策略的配置
分析問題
當一個程序集通過名字、版本、文化 和公鑰進行加載時,CLR允許程序員指定該程序集的哪些版本可以代替目前版本進行加載。這些都是通過 版本策略來實現的。所謂的版本策略,就是一個程序集版本的重定向,把加載當前這個版本定向到加載可 替代的版本。版本策略可以在以下三個級別上進行配置:
應用程序策略
發行者策略
計算機策略
這三個級別的版本策略都可以通過XML文件來進行配置。現在筆者來分別介紹 。
1.應用程序策略
應用程序策略可以在應用程序配置文件中進行配置,應用程序配置文 件位於應用程序目錄下。對於.EXE應用程序,其配置文件由exe文件名加上.config後綴名構成,例如一個 test.exe的應用程序,其配置文件就是test.exe.config。而對於任何一個Web應用程序來說,其配置文件 的文件名都是web.config。
版本策略都記錄在配置文件的assemblyBinding節點下。代碼2-7是一 個應用程序的配置文件例子,這裡只選取了本節所關心的版本策略部分內容。
代碼2-7 VersionStrategy:Web.Config
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding>
<!--對這個程序集進行版本重定向-->
<dependentAssembly>
<assemblyIdentity
name="NET.MST.Second.Compile"
publicKeyToken="60c29e5f0af3e9bb">
</assemblyIdentity>
</dependentAssembly>
<!--重定向的策略-->
<bindingRedirect oldversion="0.0.0.0-12.2.2.2"
newversion="12.3.0.0">
</bindingRedirect>
</assemblyBinding>
</runtime>
</configuration>
在代碼2-7這個配置文件中,指定了NET.MST.Second.Compile,60c29e5f0af3e9bb這個組件的版本策略 ,這個策略將0.0.0.0到12.2.2.2之間的所有版本重定向到12.3.0.0版本上。
2.發行者策略
發行者策略是針對那些被放入全局程序集緩存(GAC)中的程序集,發行者策略以一個和代碼2-6 同樣格式的配置文件形式綁定到程序集上,被一同放入GAC中。發行者策略配置文件的文件名非常古怪, 它是這樣的一個字符串:主版本號.次版本號.程序集名.dll。正因為如此,一個程序集的每個主版本/次 版本號只能有一個發行者策略。
3.計算機策略
同樣地,計算機策略同樣由一個配置文件 表示,它的格式也和代碼2-7基本類似。計算機級版本策略配置文件的文件名為:machine.config,它被 存儲在%SystemRoot% Microsoft.NET Frameworkv****CONFIG目錄下。
讀到這裡,讀者可能會有這 樣的疑問:版本策略可以在3個級別進行配置,那這些策略是如何協作的呢?按照.NET的機制,3個級別的 版本策略將會按照順序依次執行,而上一級別的執行結果將會被作為下一級別的執行輸入,圖2.6展示了 這個執行過程。
如圖2.6所示,3個級別版本策略被依照:應用程序、發行者、計算機的順序依次 執行。而其中,發行者策略是可選的,在以下兩種情況下發行者策略將不會被執行。
程序集沒有 被加入到GAC中
應用程序策略制定忽略發行者策略
在第一種情況下,根本就不存在發行者 策略配置文件,當然CLR也就不會執行發行者策略。而第二種情況,是程序員在應用程序策略中指定忽略 發行者策略,具體做法是在應用程序配置文件中加入publisherPolicy節點,並且把apply屬性值設置為no 。代碼2-8就是在代碼2-7的基礎上,指定了忽略發行者策略。
代碼2-8 VersionStrategy-NoPolisherPolicy:Web.Config
<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding>
<!--對這個程序集進行版本重定向-->
<dependentAssembly>
<assemblyIdentity
name="NET.MST.Second.Compile"
publicKeyToken="60c29e5f0af3e9bb">
</assemblyIdentity>
</dependentAssembly>
<!--重定向的策略-->
<bindingRedirect oldversion="0.0.0.0-12.2.2.2"
newversion="12.3.0.0">
</bindingRedirect>
<!--指定忽略發行者策略-->
<publisherPolicy apply="no">
</publisherPolicy>
</assemblyBinding>
</runtime>
</configuration>
答案
CLR支持在3個級別上設定版本策略,依次是:應用 程序策略、發行者策略和計算機策略。所有策略的設置都是通過修改配置文件來實現。3個級別的策略依 次會被CLR執行,而上一個策略的執行結果將被作為下一個策略的輸入。發行者策略僅僅針對那些放入GAC 的程序集,並且可以在應用程序策略中被指定忽略。