エンティティ フレームワークと検証属性を使用して wpf アプリのグローバリゼーションを実現しようとしたため、今日も同じ問題が発生しました。
私はさまざまなソリューションを試しましたが、今のところ、CustomResourceManager
Dave Sexton がこの投稿で説明しているサンプルに基づいて作成することになりました: http://www.pcreview.co.uk/forums/load-resources-string-table-database- t2892227.html
基本的に、私は my を実装DatabaseResourceManager
し、それぞれDatabaseResourceSet
から派生し、次のように実装しました。ResourceManager
ResourceSet
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 にはシングルトーン パターンが実装されているため、次のように簡単にアクセスしてデータを取得できます。
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 の投稿で述べたように、winforms は this を受け入れませんDataBaseResourceManager
が、私の場合は wpf を使用しているため、この問題はありませんでした (ただし、ResourceManager
と a の重複のため、別の小さなメモリの問題がありましたDictionaryResource
)。winformにリソースマネージャーを挿入できるかどうかはわかりませんが、それはあなたの質問を超えています. すでにご存知のもう 1 つの欠点は、がValidationAttribute
使用されるようにすべての使用済みを導出する必要があることFormatErrorMessage
です。StringLengthAttribute
、、、RequiredAttribute
などRegularExpressionAttribute
。これはエラーが発生しやすく、不器用です。残念ながら、Microsoft はここで私たちに多くの余地を与えてくれませんでした。
おそらく、将来この回答を確認して、これに関する私の調査結果を共有します。
よろしく