依存関係注入を行うためにDIフレームワークが構築されており、ローカリゼーションはあなたのサービスの1つにすぎないので、ではなく、というDIフレームワークIMOを使用する必要はありません。おそらく、提供されたILocalResources
インターフェイスについて議論する必要があります。私はコンパイル時間をサポートするのが好都合ですが、付属のインターフェイスが役立つかどうかは分かりません。そのインターフェイスはおそらくシステム内で最も変更の多いタイプになるからです。そしてそのインタフェースでは、それを実装する型/型があります。おそらく、あなたは別のデザインで行ってください。
ほとんどのローカリゼーションフレームワーク/プロバイダ/ファクトリ(または何でも)を見ると、それらはすべて文字列ベースです。このため、次のデザインについて考えてみてください。
public interface ILocalResources
{
string GetStringResource(string key);
string GetStringResource(string key, CultureInfo culture);
}
これにより、インターフェイスを変更せずに、キーとカルチャを基になるメッセージデータストアに追加することができます。もちろん、鍵は決して変えてはいけないということは、おそらく地獄だろうからです。キーは「勝ったので、このアプローチは、両方の長所を取る
public sealed class SqlLocalResources : LocalResources
{
protected override string GetStringResource(string key,
CultureInfo culture)
{
using (var db = new LocalResourcesContext())
{
return (
from resource in db.StringResources
where resource.Culture == culture.Name
where resource.Key == key
select resource.Value).FirstOrDefault();
}
}
}
:
別のアプローチは、抽象基本型である可能性があり
:
public abstract class LocalResources
{
public string OkMessage { get { return this.GetString("OK"); } }
public string CancelMessage { get { return this.GetString("Cancel"); } }
...
protected abstract string GetStringResource(string key,
CultureInfo culture);
private string GetString(string key)
{
Culture culture = CultureInfo.CurrentCulture;
string resource = GetStringResource(key, culture);
// When the resource is not found, fall back to the neutral culture.
while (resource == null && culture != CultureInfo.InvariantCulture)
{
culture = culture.Parent;
resource = this.GetStringResource(key, culture);
}
if (resource == null) throw new KeyNotFoundException(key);
return resource;
}
}
そして、このタイプの実装は、このようになります。アプリケーション全体に分散され、新しいプロパティを追加するだけで、1つの場所で行う必要があります。
container.RegisterSingleton<LocalResources>(new SqlLocalResources());
そしてLocalResources
タイプは、すべての作業を行い、正確に1つの抽象メソッドを持っているので、要求しないようにするキャッシュを追加するデコレータを作成することは簡単です:あなたのfavorite DIライブラリを使用すると、あなたはこのような実装を登録することができます次のように、デコレータを適用することができます
public sealed class CachedLocalResources : LocalResources
{
private readonly Dictionary<CultureInfo, Dictionary<string, string>> cache =
new Dictionary<CultureInfo, Dictionary<string, string>>();
private readonly LocalResources decoratee;
public CachedLocalResources(LocalResources decoratee) { this.decoratee = decoratee; }
protected override string GetStringResource(string key, CultureInfo culture) {
lock (this.cache) {
string res;
var cultureCache = this.GetCultureCache(culture);
if (!cultureCache.TryGetValue(key, out res)) {
cultureCache[key] = res= this.decoratee.GetStringResource(key, culture);
}
return res;
}
}
private Dictionary<string, string> GetCultureCache(CultureInfo culture) {
Dictionary<string, string> cultureCache;
if (!this.cache.TryGetValue(culture, out cultureCache)) {
this.cache[culture] = cultureCache = new Dictionary<string, string>();
}
return cultureCache;
}
}
:データベースから同じデータ
container.RegisterSingleton<LocalResources>(
new CachedLocalResources(new SqlLocalResources()));
しないでくださいこのデコレータは文字列リソースを無期限にキャッシュするため、メモリリークの原因となる可能性があります。そのため、文字列をWeakReference
インスタンスにラップするか、何らかの有効期限があります。しかし、既存の実装を変更することなくキャッシングを適用できるというアイデアです。
こちらがお役に立てば幸いです。
また、 'ILocalResources'インタフェース用の拡張メソッドを実装することもできますが、その欠点はプロパティの代わりにメソッドがあることです。しかし、それはおそらくそれほど悪くはありません。 – Steven