私のアプリケーションで「利用可能な言語」のリストを提示したいという状況があります (ちなみに、それがオッズを作る場合、これは ASP .NET MVC 3 アプリケーションです)。ビルドに含まれているのはresxファイルだけであるため、このリストを何らかの方法で自動的に取得できると思いました(英語の英国、ドイツ語のオーストリアなどをサポートする必要はありません。英語またはドイツ語のみです)。以下に提示するスキーム(少し集中的なアプローチであるため、シングルトンとして実装されています)。
問題は、一部のマシンではそのようなリソースがなくても「アラビア語」を返し、私のマシンでは (VS 2012 をインストールしたため) すべてを返すことです (これは、2 つの実際のカルチャとアラビア語だけを返すよりも理にかなっていますしかし、ResourceManager はこの情報を取得できるように設計されていないように見えるので、おそらく文句を言うべきではありません)。これがスキームです...
(私は Strings.resx と Strings.de.resx ファイルを持っています)
IEnumerable<CultureInfo> cultures =
CultureInfo.GetCultures(CultureTypes.NeutralCultures)
.Where(c =>
{
// Exclude the invariant culture and then load up
// an arbitrary string so the resource manager
// loads a resource set, then get the set for the
// current culture specifically and it is, sometimes
// (I thought always but I was wrong) null if no
// set exists
if (c.LCID == CultureInfo.InvariantCulture.LCID)
return false;
var rm = Strings.ResourceManager;
rm.GetString("HELLO", c);
return rm.GetResourceSet(c, false, false) != null;
});
それで、言語固有のディレクトリが次のように存在するかどうかに基づいて、これを行うことができると思いました。
var neutralCulture = new[]
{
CultureInfo
.CreateSpecificCulture(((NeutralResourcesLanguageAttribute)
Assembly
.GetExecutingAssembly()
.GetCustomAttributes(
typeof (NeutralResourcesLanguageAttribute),
false)[0])
.CultureName)
};
IEnumerable<CultureInfo> cultures =
CultureInfo.GetCultures(CultureTypes.NeutralCultures)
.Where(c => Directory.Exists(c.TwoLetterISOLanguageName))
.Union(neutralCulture);
これは「機能します」(英語とドイツ語を返す限り)が、誰かがフォルダーを作成してすべてを台無しにするなどのランダムな問題が発生しやすいため、非常に安定したアプローチではないと思います。おそらく、いくつかのより賢明なチェックでこれらの問題を軽減できますが(where句はより洗練されたものを求めています)、ここで質問があります(最終的に)...
今のところ、設定ファイルを使用して完全にシンプルに保つことを考えていますが、これを行うより良い方法はありますか (または、安全な方法で自動的に行うことができますか) ?