5

方案企業庫驗證應用程序塊和國際

一個.NET/WPF桌面應用程序應該本地化(或MS而言全球化),以不同的語言不是英語。也就是說,UI需要完全採用(標籤,圖標......)。

但是,應用程序的日誌文件條目,審計跟蹤條目和其他輸出應該保持英文,以便英語服務/支持人員對其進行審閱。他們不會說法語或中文。

該應用程序依靠RESX文件來完成本地化。

企業庫驗證塊用於驗證對象模型上的業務規則。

現在假設有一種服務在執行真實的業務邏輯之前驗證給定的對象模型參數。在某些情況下,它會收到無​​效的對象模型參數,但會盡最大努力繼續執行。但是,提供無效的對象模型數據應記錄在審計跟蹤和日誌文件中。

使用驗證塊的服務示例。

public class Service : IService 
{ 
    public void MyMethod(MyObjectModelObject obj) 
    { 
     Validator validator = ValidationFactory.CreateValidator(typeof(MyObjectModelObject)); 
     ValidationResults results = validator.Validate(this); 

     // !!! The messages in the validation results are now already localized to CurrentCulture. 

     // ... build a log message: msg 
     if (results.Count > 0) 
     { 
      Logger.Log(msg); 
     } 
    } 
} 

如上代碼評論說,當你所謂的validate()在EnterpriseLibrary驗證,驗證消息已經定位於法國,你有沒有機會,並寫入到一個如英文日誌文件。

在我們的應用程序的其他領域,我們使用一個消息類來封裝資源ID和參數,直到我們確定我們想要使用哪種文化來解析實際的字符串值。您可以將其稱爲延期資源解決方案。

任何想法如何向企業圖書館驗證塊引入類似的機制?想法而已:

  • 暫時切換的CurrentCulture(我不喜歡這一點,它解決了只是問題的一半)
  • 補丁企業庫驗證模塊(我不喜歡這樣,太)

感謝您的幫助和分享想法!

回答

4

當我們需要延期資源解析時,我們放棄了使用MessageTemplateResourceName,而是將我們的資源ID設爲MessageTemplate屬性。然後,我們稍後使用該id來查找使用當前文化的資源字符串值。

我們對id的命名約定進行了標準化,如下所示:RULESET_RULESETQUALIFIER_OPERATION_OBJECT_PROPERTY_VALIDATIONTYPE。例如RULESET_BMW_INSERT_CAR_YEAR_RANGERULESET_BMW_UPDATE_CAR_COLOR_LENGTH

在VAB配置,這將是這個樣子:

<property name="Color"> 
    <validator lowerBound="0" lowerBoundType="Ignore" upperBound="50" 
    upperBoundType="Inclusive" negated="false" messageTemplate="RULESET_BMW_INSERT_CAR_COLOR_LENGTH" 
    messageTemplateResourceName="" messageTemplateResourceType="" 
    tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
    name="String Length Validator" /> 
        </property> 

主要的缺點是你失去了輕鬆的使用消息模板的令牌,使該消息略微動態的能力。這可以完成,但令牌值必須存儲在某個地方(例如,你的消息類),以便它們可以在消息字符串評估後被替換。

您可能還想考慮爲每個目標消息創建多個資源文件。也就是說,一個用戶消息資源和一個技術消息資源。因此,您可以爲用戶消息提供UserMessages.resources,UserMessages.fr-BE.resources。然後在另一個資源文件中複製具有不同日誌消息的ids(LogMessages.resources)。這樣您可以獲得日誌消息的其他技術信息。儘管這可能是過度的。

然後,我們使用ResourceManager訪問字符串值:

ResourceManager userResourceManager = 
    new ResourceManager("UserMessages", Assembly.GetExecutingAssembly()); 

string userMessage = userResourceManager.GetString(resourceId); 

ResourceManager logResourceManager = 
    new ResourceManager("LogMessages", Assembly.GetExecutingAssembly()); 

// Can also try to use InvariantCulture instead of "en" 
string messageToLog = logResourceManager.GetString(resourceId, new CultureInfo("en")); 
//alternative to ensure you get the english user message value: 
// string messageToLog = userResourceManager.GetString(resourceId, new CultureInfo("en")); 


你可以抽象送人到一個輔助類或把它添加到您的郵件類。您可能還需要構建一些代碼來提取ValidationResults並使用所需的信息創建消息類。

+0

非常感謝您的輸入Tuzo!所提到的缺點對我們來說是一個很大的缺點 - 我們肯定需要動態組合的消息。我們目前正在改變EntLib Validation Block的實現來完全使用我們的消息類而不是急切解析的字符串。一個相當麻煩的任務,但最終我們在整個應用程序中都有一個方法。更大的缺點是維護,但驗證塊在最新版本的核心概念上一直非常穩定。 – 2010-08-16 14:23:32