今天我有同樣的問題,因爲我試圖讓全球化發生的實體框架和驗證屬性的WPF應用程序。
我嘗試了不同的解決方案,並就目前而言,我結束了創建基於戴夫塞克斯頓介紹在這個崗位樣品CustomResourceManager
:http://www.pcreview.co.uk/forums/load-resources-string-table-database-t2892227.html
基本上,我已經實現了我的DatabaseResourceManager
分別從ResourceManager
和ResourceSet
衍生DatabaseResourceSet
像這樣:
的DatabaseResourceManager
實現:
public class DatabaseResourceManager : ResourceManager
{
#region Singleton pattern http://msdn.microsoft.com/en-us/library/ff650316.aspx
private static volatile DatabaseResourceManager instance;
private static object syncRoot = new Object();
private DatabaseResourceManager() : base() { }
public static DatabaseResourceManager Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DatabaseResourceManager();
}
}
return instance;
}
}
#endregion
protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
if (culture == null)
culture = CultureInfo.InvariantCulture;
return new DatabaseResourceSet(culture);
}
}
而且DatabaseResourceSet
實現:
public class DatabaseResourceSet : ResourceSet
{
private readonly CultureInfo culture;
private static readonly Dictionary<string, Hashtable> cachedResources = new Dictionary<string, Hashtable>();
public DatabaseResourceSet(CultureInfo culture)
{
if (culture == null)
throw new ArgumentNullException("culture");
this.culture = culture;
ReadResources();
}
protected override void ReadResources()
{
if (cachedResources.ContainsKey(culture.Name))
// retrieve cached resource set
{
Table = cachedResources[culture.Name];
return;
}
using (MyDatabaseContext db = new MyDatabaseContext())
{
var translations = from t in db.Translations
where t.CultureIso == culture.Name
select t;
foreach (var translation in translations)
{
Table.Add(translation.Chave, translation.Valor);
}
}
cachedResources[culture.Name] = Table;
}
}
由於我DataBaseResourceManager有singletone模式實現的,我可以很容易地訪問,並得到像這樣的數據:
public class LocalizedRequiredAttribute : RequiredAttribute
{
public LocalizedRequiredAttribute() : base()
{
}
public override string FormatErrorMessage(string name)
{
string localErrorMessage = DatabaseResourceManager.Instance.GetString(this.ErrorMessageResourceName) ?? ErrorMessage ?? "{0} is required"; //probably DataAnnotationsResources.RequiredAttribute_ValidationError would is a better option
return string.Format(System.Globalization.CultureInfo.CurrentCulture, localErrorMessage, new object[] { name });
}
}
現在的缺點:
就像說在pcreview post中,winforms不接受這個DataBaseResourceManager
,但在我的情況下,因爲我使用wpf,所以我沒有這個問題(但由於的重複而導致另一個小內存問題和DictionaryResource
)。不知道你是否可以在winforms中注入資源管理器,但這超出了你的問題。 另一個缺點是,您已經知道,我們必須導出所有使用的ValidationAttribute
,以便使用FormatErrorMessage
。 StringLengthAttribute
,RequiredAttribute
,RegularExpressionAttribute
等等。這很容易出錯和笨拙。不幸的是,微軟在這裏沒有給我們太多空間。
希望我幫忙,可能我會在將來回顧這個答案,分享我的發現。
Regards