封裝和部署資源
更新:2007 年 11 月
.NET Framework 使用中樞和輪輻模型來封裝和部署資源。中樞為主要組件,包含無法當地語系化的可執行程式碼,和稱為中性或預設文化特性的單一文化特性的資源。預設文化特性為應用程式的回溯文化特性。各個輪輻都連接至含有單一文化特性資源 (但不包含任何程式碼) 的附屬組件。
這個模型有幾個優點:
您可以在已部署應用程式之後,遞增地加入新文化特性的資源。因為特定文化特性資源的後續開發可能需要非常大量的時間,這允許您先發行主應用程式,而在日後發行特定文化特性資源。
您可以更新並變更應用程式的附屬組件,而不需重新編譯應用程式。
應用程式只需載入那些包含特定文化特性所需資源的附屬組件。這大幅降低系統資源的使用。
然而,這個模型也有缺點:
您必須管理多個資源集合。
測試應用程式的初期成本會增加,因為您必須測試數個組態。注意,就長期而言,測試一個具有數個附屬組件的核心應用程式,較測試並維護數個平行的國際版本,要來得更容易並且更便宜。
資源命名規範
當您封裝應用程式的資源時,您必須使用 Common Language Runtime 所要求的資源命名規範來命名它們。Runtime 根據它的文化特性簽章 (或名稱) 來識別資源。每個文化特性都會被指定成唯一名稱,該名稱是由和語言關聯之兩個小寫字母的文化特性名稱,以及在必要時和國家或地區關聯之兩個大寫字母的子文化特性名稱所組合而成。子文化特性名稱接在文化特性名稱之後,以破折號 (-) 分隔。範例包括 ja-JP 代表日本的日文、en-US 代表美國的英文,或 de-DE 代表德國的德文 (相對於另一個選擇,例如 de-AT 代表奧地利的德文)。如需文化特性名稱的完整清單,請參閱 CultureInfo 類別。
資源回溯過程
封裝並部署資源的中樞和輪輻模型使用回溯過程來找出適當資源。如果應用程式使用者要求無法使用的 ResourceSet,Common Language Runtime 會在文化特性的階層架構中搜尋最接近使用者要求的適當後援資源,而引發例外狀況只是做為最後手段。在階層架構的各個層級上,如果找到適當資源,Runtime 就使用它。如果未找到資源,會在下一層級繼續搜尋。下列步驟說明了資源回溯過程:
Runtime 首先會檢查符合應用程式所要求之文化特性組件的全域組件快取。
全域組件快取可以儲存許多應用程式所共用的資源組件。這讓您免於必須包含特定資源集合於您所建立的一切應用程式的目錄結構中。如果執行階段找到組件的參考,它會在組件中搜尋所要求的資源。如果它找到組件中的項目,它會使用要求的資源。如果它沒找到項目,它將繼續搜尋。
Runtime 接下來檢查目前執行中組件的目錄,找出符合所要求文化特性的目錄。如果它找到目錄,它會在那目錄中搜尋所要求文化特性的有效附屬組件。Runtime 接著在附屬組件中搜尋要求的資源。如果在組件中找到資源,即使用它。如果它未找到資源,則繼續搜尋。
Runtime 接下來於全域組件快取中再度搜尋,此時要找出所要求資源的父組件。如果父組件存在於全域組件快取,Runtime 則在組件中搜尋要求的資源。
父組件被定義為適當的回溯文化特性。將父組件視為最適候選者;假如有任何資源要比擲回例外狀況更合適的話。這個過程也允許您重複使用資源。只要子文化特性不需要當地語系化所要求的資源,您必須包括特定資源在父層級。例如,如果您提供附屬組件給 en (中性英文)、en-GB (在英國所說的英文) 和 en-US (在美國所說的英文),則 en 附屬組件會包含共通的專門用語,而 en-GB 和 en-US 附屬組件可能只對那些不同的詞彙進行覆寫。
Runtime 接下來檢查目前執行中組件的目錄,看看它是否包含父目錄。如果父目錄存在,Runtime 在目錄中搜尋父文化特性的有效附屬組件。如果它找到組件,Runtime 在組件中搜尋要求的資源。如果找到資源,即使用它。如果它未找到資源,則繼續搜尋。
Runtime 接下來在許多可能層級中全面搜尋父組件 (如先前步驟)。每一個文化特性只有一個父文化特性,但是父文化特性可擁有自己的父文化特性。
如果已經搜尋原先指定的文化特性和所有父文化特性卻仍未找到資源,則會使用預設 (回溯) 文化特性的資源。從 .NET Framework 2.0 版開始,您就可以將資源的最終後援位置指定為附屬組件而非主要組件。利用 NeutralResourcesLanguageAttribute 加上 UltimateResourceFallbackLocation 列舉型別,您就可以控制資源的最終後援位置是要在附屬組件或主要組件內。
注意事項: 預設資源是唯一與主要組件一起編譯的資源。除非您利用 NeutralResourcesLanguageAttribute 指定附屬組件,否則它便是最終後援 (最終父代)。因此,強烈建議您,永遠要在您的主要組件中包含預設資源集合。這有助於確保例外狀況不會被擲回。藉著包含預設資源檔,您可替所有資源提供回溯,並確保至少有一個資源一直為使用者存在著,即使它不是特定文化特性的。
最後,如果執行階段沒有找到預設 (回溯) 文化特性的資源,將會擲回例外狀況以表示資源無法找到。
就如何進行所要求資源的搜尋的範例來說,假定使用者要求資源被當地語系化為墨西哥西班牙文。依照上述資源命名規範,Runtime 首先在全域組件快取中搜尋符合所要求文化特性 "es-MX" 的組件。若找到它,Runtime 接著在目前執行中組件的目錄搜尋 "es-MX" 目錄。若失敗,Runtime 再度於全域組件快取中搜尋反映適當回溯文化特性的父組件 - 在這個案例中為 "es" (西班牙文)。如果沒有找到父組件,Runtime 在父組件的所有可能層級上搜尋 "es-MX" 文化特性,直到尋獲對應的資源為止。如果未找到資源,Runtime 使用預設文化特性的資源。
附屬組件的最終後援
從 .NET Framework 2.0 版開始,您就能選擇性地從主要組件中移除資源,並指定從與特定文化特性對應的附屬組件中找到最終後援。若要控制後援處理序,您可以使用 NeutralResourcesLanguageAttribute。NeutralResourcesLanguageAttribute 類別中新增了一個建構函式,它使用額外的 UltimateResourceFallbackLocation 參數指定 ResourceManager 從中抽取後援資源的位置:即主要組件或附屬組件。
下列範例將示範如何在類別層級套用屬性:
[assembly: NeutralResourcesLanguageAttribute("de" , UltimateResourceFallbackLocation.Satellite)]
對於最終後援位置,它指示 ResourceManager 資源在目前正在執行的組件之目錄的 "de" 子目錄中尋找資源。
建議的封裝替代方式
由於時間或經費限制,您若要為應用程式所支援的每個子文化特性建立一組資源,可能並不可行。在這個情形中,您可以建立父文化特性的單一附屬組件,供所有相關子文化特性使用。例如,您可以提供單一英文附屬組件 (en) 給要求地區特性英文資源的使用者擷取,和單一德文附屬組件 (de) 給要求地區特性德文資源的使用者。例如,對於德國德文 (de-DE)、奧地利德文 (de-AT) 和瑞士德文 (de-CH) 的要求將會回溯至德文附屬組件 (de)。請小心選取要和主要組件一起編譯的預設資源。預設資源為最終回溯,並因此應該是您應用程式的大多數使用者所將要求的資源。雖然這個方案會部署比較不是特定文化特性的資源,但它可以大幅降低您應用程式的當地語系化成本。