次の方法で共有


.NET でのローカライズ

ローカライズとは、アプリケーションがサポートするカルチャごとに、アプリケーションのリソースをローカライズされたバージョンに変換するプロセスです。 ローカライズの手順に進むには、 ローカライズ可能性の確認 手順を完了して、グローバル化されたアプリケーションがローカライズの準備ができていることを確認する必要があります。

ローカライズの準備ができているアプリケーションは、すべてのユーザー インターフェイス要素を含むブロックと実行可能コードを含むブロックという 2 つの概念ブロックに分けられます。 ユーザー インターフェイス ブロックには、ニュートラル カルチャの文字列、エラー メッセージ、ダイアログ ボックス、メニュー、埋め込みオブジェクト リソースなどのローカライズ可能なユーザー インターフェイス要素のみが含まれます。 コード ブロックには、サポートされているすべてのカルチャで使用されるアプリケーション コードのみが含まれています。 共通言語ランタイムは、アプリケーションの実行可能コードとそのリソースを分離するサテライト アセンブリ リソース モデルをサポートします。 このモデルの実装の詳細については、「 .NET のリソース」を参照してください。

アプリケーションのローカライズされたバージョンごとに、ターゲット カルチャに適した言語に翻訳されたローカライズされたユーザー インターフェイス ブロックを含む新しいサテライト アセンブリを追加します。 すべての文化向けのコード ブロックは同じままにしておくべきです。 ローカライズされたバージョンのユーザー インターフェイス ブロックとコード ブロックを組み合わせることで、アプリケーションのローカライズされたバージョンが生成されます。

この記事では、 IStringLocalizer<T>IStringLocalizerFactory の実装を使用する方法について説明します。 この記事のソース コードの例はすべて、 Microsoft.Extensions.Localization と NuGet パッケージ Microsoft.Extensions.Hosting に依存しています。 ホスティングの詳細については、「 .NET 汎用ホスト」を参照してください。

リソース ファイル

ローカライズ可能な文字列を分離するための主なメカニズムは、 リソース ファイルを使用することです。 リソース ファイルは、 .resx ファイル拡張子を持つ XML ファイルです。 リソースファイルは、消費するアプリケーションの実行前に翻訳されます。つまり、静的に存在する翻訳コンテンツを表しています。 最も一般的なリソース ファイル名にはロケール識別子が含まれており、次の形式になります。

<FullTypeName><.Locale>.resx

場所は:

  • <FullTypeName>は、特定の種類のローカライズ可能なリソースを表します。
  • 省略可能な <.Locale> は、リソース ファイルの内容のロケールを表します。

ロケールの指定

ロケールでは、最小限で言語を定義する必要がありますが、カルチャ (地域言語)、さらには国や地域を定義することもできます。 これらのセグメントは、通常、 - 文字で区切られます。 カルチャの特定性が追加されると、最適な一致が優先される場所に "カルチャ フォールバック" ルールが適用されます。 ロケールは既知の言語タグにマップする必要があります。 詳細については、CultureInfo.Nameを参照してください。

カルチャフォールバックのシナリオ

ローカライズされたアプリがさまざまなセルビアロケールをサポートしており、その MessageService用に次のリソース ファイルがあるとします。

ファイル 地域言語 国番号
MessageService.sr-Cyrl-RS.resx (キリル文字、セルビア) RS
MessageService.sr-Cyrl.resx キリル
MessageService.sr-Latn-BA.resx (ラテン、ボスニア・ヘルツェゴビナ) 文学士
MessageService.sr-Latn-ME.resx (ラテン、モンテネグロ)
MessageService.sr-Latn-RS.resx (ラテン、セルビア) RS
MessageService.sr-Latn.resx ラテン語
MessageService.sr.resx ラテン語
MessageService.resx

言語の既定の地域言語。

CultureInfo.CurrentCulture"sr-Cyrl-RS"ローカライズのカルチャに設定してアプリを実行すると、次の順序でファイルの解決が試行されます。

  1. MessageService.sr-Cyrl-RS.resx
  2. MessageService.sr-Cyrl.resx
  3. MessageService.sr.resx
  4. MessageService.resx

ただし、CultureInfo.CurrentCulture"sr-Latn-BA" のカルチャに設定してアプリを実行していた場合、ローカライズでは次の順序でファイルの解決を試みます。

  1. MessageService.sr-Latn-BA.resx
  2. MessageService.sr-Latn.resx
  3. MessageService.sr.resx
  4. MessageService.resx

対応する一致がない場合、"カルチャ フォールバック" ルールはロケールを無視します。一致するものが見つからない場合は、リソース ファイル番号 4 が選択されます。 カルチャが "fr-FR" に設定されている場合、ローカライズは 最終的に MessageService.resx ファイルに落ち、問題が発生する可能性があります。 詳細については、「 リソースフォールバックプロセス」を参照してください。

リソースの参照

リソース ファイルは、参照ルーチンの一部として自動的に解決されます。 プロジェクト ファイル名がプロジェクトのルート名前空間と異なる場合、アセンブリ名が異なる場合があります。 これにより、リソースの参照が正常に行われなくなる可能性があります。 この不一致に対処するには、 RootNamespaceAttribute を使用してローカライズ サービスにヒントを提供します。 指定すると、リソース参照中に使用されます。

このプロジェクト例は example.csproj という名前で、 example.dllexample.exeを作成しますが、 Localization.Example 名前空間が使用されます。 この不一致を修正するには、 assembly レベルの属性を適用します。

[assembly: RootNamespace("Localization.Example")]

ローカライズ サービスを登録する

ローカライズ サービスを登録するには、サービスの構成中に AddLocalization 拡張メソッドのいずれかを呼び出します。 これにより、次の種類の依存関係挿入 (DI) が有効になります。

ローカライズ オプションを構成する

AddLocalization(IServiceCollection, Action<LocalizationOptions>) オーバーロードは、setupAction型のAction<LocalizationOptions> パラメーターを受け取ります。 これにより、ローカライズ オプションを構成できます。

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Services.AddLocalization(options =>
{
    options.ResourcesPath = "Resources";
});

// Omitted for brevity.

リソース ファイルはプロジェクト内の任意の場所に存在できますが、成功することが証明されている一般的なプラクティスがあります。 多くの場合、抵抗が最も少ないパスに従います。 前述の C# コードでは、次のことが行われます。

  • 既定のホスト アプリ ビルダーを作成します。
  • AddLocalizationLocalizationOptions.ResourcesPathとして指定して、サービス コレクションの"Resources"を呼び出します。

これにより、ローカリゼーション サービスはリソース ファイルの Resources ディレクトリを検索します。

IStringLocalizer<T>IStringLocalizerFactory を使用する

ローカライズ サービスを 登録 (および必要に応じて 構成) したら、DI で次の種類を使用できます。

ローカライズされた文字列を返すメッセージ サービスを作成するには、次の MessageServiceを考慮してください。

using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Localization;

namespace Localization.Example;

public sealed class MessageService(IStringLocalizer<MessageService> localizer)
{
    [return: NotNullIfNotNull(nameof(localizer))]
    public string? GetGreetingMessage()
    {
        LocalizedString localizedString = localizer["GreetingMessage"];

        return localizedString;
    }
}

前述の C# コードでは:

  • IStringLocalizer<MessageService> localizer フィールドが宣言されています。
  • プライマリ コンストラクターは、 IStringLocalizer<MessageService> パラメーターを定義し、 localizer 引数としてキャプチャします。
  • GetGreetingMessage メソッドは、IStringLocalizer.Item[String]を引数として渡す"GreetingMessage"を呼び出します。

IStringLocalizerでは、パラメーター化された文字列リソースもサポートされています。次のParameterizedMessageServiceを考慮してください。

using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Localization;

namespace Localization.Example;

public class ParameterizedMessageService(IStringLocalizerFactory factory)
{
    private readonly IStringLocalizer _localizer =
        factory.Create(typeof(ParameterizedMessageService));

    [return: NotNullIfNotNull(nameof(_localizer))]
    public string? GetFormattedMessage(DateTime dateTime, double dinnerPrice)
    {
        LocalizedString localizedString = _localizer["DinnerPriceFormat", dateTime, dinnerPrice];

        return localizedString;
    }
}

前述の C# コードでは:

  • IStringLocalizer _localizer フィールドが宣言されています。
  • プライマリ コンストラクターは、IStringLocalizerFactory パラメーターを受け取ります。これは、IStringLocalizer型からParameterizedMessageServiceを作成するために使用され、_localizer フィールドに割り当てられます。
  • GetFormattedMessage メソッドは、IStringLocalizer.Item[String, Object[]]を呼び出し、"DinnerPriceFormat"dateTime オブジェクト、およびdinnerPriceを引数として渡します。

Von Bedeutung

IStringLocalizerFactoryは必要ありません。 サービスを利用する人々が IStringLocalizer<T> を必要とすることが望ましいです。

両方のIStringLocalizer.Item[]インデクサーは、LocalizedStringを返し、そのLocalizedStringにはstring?への暗黙的な変換があります。

すべてをまとめる

メッセージ サービスとローカライズ ファイルとリソース ファイルの両方を使用してアプリを例示するには、次の Program.cs ファイルを検討してください。

using System.Globalization;
using Localization.Example;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using static System.Console;
using static System.Text.Encoding;

[assembly: RootNamespace("Localization.Example")]

OutputEncoding = Unicode;

if (args is [var cultureName])
{
    CultureInfo.CurrentCulture =
        CultureInfo.CurrentUICulture =
            CultureInfo.GetCultureInfo(cultureName);
}

HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);

builder.Services.AddLocalization();
builder.Services.AddTransient<MessageService>();
builder.Services.AddTransient<ParameterizedMessageService>();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

using IHost host = builder.Build();

IServiceProvider services = host.Services;

ILogger logger =
    services.GetRequiredService<ILoggerFactory>()
        .CreateLogger("Localization.Example");

MessageService messageService =
    services.GetRequiredService<MessageService>();
logger.LogWarning(
    "{Msg}",
    messageService.GetGreetingMessage());

ParameterizedMessageService parameterizedMessageService =
    services.GetRequiredService<ParameterizedMessageService>();
logger.LogWarning(
    "{Msg}",
    parameterizedMessageService.GetFormattedMessage(
        DateTime.Today.AddDays(-3), 37.63));

await host.RunAsync();

前述の C# コードでは:

  • RootNamespaceAttributeは、ルート名前空間として"Localization.Example"を設定します。
  • Console.OutputEncoding は、Encoding.Unicodeに割り当てられます。
  • argsに1つの引数を渡すと、CultureInfo.CurrentCultureを与えられたときのCultureInfo.CurrentUICultureの結果がCultureInfo.GetCultureInfo(String)arg[0]に割り当てられます。
  • Host既定値で作成されます。
  • ローカライズ サービス、 MessageService、および ParameterizedMessageService は、DI の IServiceCollection に登録されます。
  • ノイズを除去するために、ログ記録は警告よりも低いログ レベルを無視するように構成されます。
  • MessageServiceIServiceProvider インスタンスから解決され、結果のメッセージがログに記録されます。
  • ParameterizedMessageServiceIServiceProvider インスタンスから解決され、結果として生成される書式設定されたメッセージがログに記録されます。

*MessageService クラスは、1 つのエントリを持つ .resx ファイルのセットを定義します。 MessageService 以降では、 リソース ファイルのコンテンツの例を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="GreetingMessage" xml:space="preserve">
    <value>Hi friends, the ".NET" developer community is excited to see you here!</value>
  </data>
</root>

MessageService.sr-Cyrl-RS.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="GreetingMessage" xml:space="preserve">
    <value>Здраво пријатељи, ".NЕТ" девелопер заједница је узбуђена што вас види овде!</value>
  </data>
</root>

MessageService.sr-Latn.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="GreetingMessage" xml:space="preserve">
    <value>Zdravo prijatelji, ".NET" developer zajednica je uzbuđena što vas vidi ovde!</value>
  </data>
</root>

ParameterizedMessageService 以降、 リソース ファイルのコンテンツの例を次に示します。

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="DinnerPriceFormat" xml:space="preserve">
    <value>On {0:D} my dinner cost {1:C}.</value>
  </data>
</root>

ParameterizedMessageService.sr-Cyrl-RS.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="DinnerPriceFormat" xml:space="preserve">
    <value>У {0:D} моја вечера је коштала {1:C}.</value>
  </data>
</root>

ParameterizedMessageService.sr-Latn.resx:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="DinnerPriceFormat" xml:space="preserve">
    <value>U {0:D} moja večera je koštala {1:C}.</value>
  </data>
</root>

ヒント

簡潔にするために、すべてのリソース ファイルの XML コメント、スキーマ、および <resheader> 要素は意図的に省略されます。

実行例

次の実行例は、ターゲットロケールを指定して、さまざまなローカライズされた出力を示しています。

"sr-Latn"を検討してください。

dotnet run --project .\example\example.csproj sr-Latn

warn: Localization.Example[0]
      Zdravo prijatelji, ".NET" developer zajednica je uzbuđena što vas vidi ovde!
warn: Localization.Example[0]
      U utorak, 03. avgust 2021. moja večera je koštala 37,63 ¤.

プロジェクトを実行するために .NET CLI の引数を省略すると、既定のシステム カルチャが使用されます。この場合は、次"en-US"

dotnet run --project .\example\example.csproj

warn: Localization.Example[0]
      Hi friends, the ".NET" developer community is excited to see you here!
warn: Localization.Example[0]
      On Tuesday, August 3, 2021 my dinner cost $37.63.

"sr-Cryl-RS"渡すと、適切な対応するリソース ファイルが見つかり、ローカライズが適用されます。

dotnet run --project .\example\example.csproj sr-Cryl-RS

warn: Localization.Example[0]
      Здраво пријатељи, ".NЕТ" девелопер заједница је узбуђена што вас види овде!
warn: Localization.Example[0]
      У уторак, 03. август 2021. моја вечера је коштала 38 RSD.

サンプル アプリケーションは "fr-CA"用のリソース ファイルを提供しませんが、そのカルチャで呼び出されると、ローカライズされていないリソース ファイルが使用されます。

Warnung

カルチャは見つかりましたが、正しいリソース ファイルは見つからないため、書式設定が適用されると、最終的に部分的なローカライズが行われます。

dotnet run --project .\example\example.csproj fr-CA

warn: Localization.Example[0]
     Hi friends, the ".NET" developer community is excited to see you here!
warn: Localization.Example[0]
     On mardi 3 août 2021 my dinner cost 37,63 $.

こちらも参照ください