所謂組件屬性的 design-time 多語言支援,是讓你的組件在使用的時候對不同語言版本的IDE顯示對應的語言版本描述。 例如,很多專業的組件都有這樣的屬性,你在中文版的 .net studio 看到的屬性描述都是中文的, 而在日文下看到的描述則是日文的。
在編寫 .Net Component 的時候,如何添加 design-time 的多語言支援呢?
Anyway, "Imitation is the sincerest form of flattery". 我們來看看微軟是怎麼做。
以下是微軟類庫中CheckBox的虛擬碼片斷分析,
public class CheckBox
{
....
// Properties
[SRDescription("CheckBoxAutoCheckDescrKey")]
public bool AutoCheck { get; set; }
[SRDescription("CheckBoxCheckAlignDescrKey")]
public ContentAlignment CheckAlign { get; set; }
[SRDescription("CheckBoxCheckedDescrKey")]
public bool Checked { get; set; }
...
}
通過反射機制,.Net Studio IDE 會從組件屬性中聲明的 SRDescription 中擷取描述字串,然後在屬性視窗中顯示。
SRDescription 是 類 SRDescriptionAttribute 的執行個體。 SRDescriptionAttribute 繼承了 DescriptionAttribute, 提供了獲得本地化的描述的實現 -- public override string Description { get; }, 偽碼如下:
// the declamation of the class SRDescriptionAttribute
class SRDescriptionAttribute : DescriptionAttribute
{
// constructor descripton key specified the key of the resouce string.
public SRDescriptionAttribute(string descriptionKey);
// Return the localized description string, according to the description_Key get the description from the assembly resource source.
public override string Description { get; }
...
}
簡而言之,為了獲得多語言支援,只要在 SRDescriptionAttribute 類的 Description 的實現中,根據不同的語言擷取相對應的描述字串便可以了。
那麼接下來,我們要如何做呢?
首先,依上所述,從 DescriptionAttribute 通過繼承,建立一個我們自己的 ResourceDescriptionAttribute。由於這個類是設計時用的,我們可以把它標記為 internal,阻止外面的非法訪問。
重寫 Description 的實現, 根據不同的語言獲得不同的描述字串。 根據具體情況,一般可以把 Default 的語言類型相對應的資源檔嵌入到組件的Main Assembly裡面,作為fall back資源,而把其他語言的資源檔獨立編譯到另外的一個專門提供本地化資源的 Resource Assembly。 Description的實現裡面做一個小小的處理,根據當前的語言版本去尋找 Resource Assembly, 如果沒有發現當前環境相應的語言的資源,或者無法讀取 Resource Assemly,就應該採用Main Assembly的 fall back 資源檔。 這也是稱之為 fall back 資源檔的來由, (fall back 有些 backup 的含義)。
添加資源檔。 為不同的組件屬性添加不同的描述字串。 注意,不同語言版本的資源檔要保持Key的一致性。
例如,比較著名的 Crystal Report 大體也是就是這樣實現的。 查看原生 GAC, 你應該可以找到這兩個 Assembly, CrystalDecisions.Web.dll 和 CrystalDecisions.Web.resources.dll。 其中,CrystalDecisions.Web.dll 就是上面提到的 Main Assembly, 裡麵包含了 Web form 下的組件實現,以及 Default 語言的資源檔也就是 fall back 資源, CrystalDecisions.Web.resources.dll 就是Resource Assembly, 提供了相應的本地化資源檔。
當然這個是很 professional 的做法,若你的 Component 不必要那麼強調國際化本地化的支援,乾脆直接使用DescriptionAttribute把相應的描述 hard code 到類實現就可以了。 畢竟,在變化到來之前,任何的提前設計,都應先假設為過度的。
例如:
[Description("hard code your description here")]
public Image MyImage {
get {
// Insert code here.
return image1;
}
set {
// Insert code here.
}
}
有關如何根據操作資源以及資源本地化支援,已經超過了本文的討論範疇,請參閱msdn。