Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
La localisation est le processus de traduction des ressources d’une application en versions localisées pour chaque culture prise en charge par l’application. Vous devez passer à l’étape de localisation uniquement après avoir effectué l’étape de révision de localisabilité pour vérifier que l’application globalisée est prête pour la localisation.
Une application prête pour la localisation est séparée en deux blocs conceptuels : un bloc qui contient tous les éléments d’interface utilisateur et un bloc qui contient du code exécutable. Le bloc d’interface utilisateur contient uniquement des éléments d’interface utilisateur localisables tels que des chaînes, des messages d’erreur, des boîtes de dialogue, des menus, des ressources d’objet incorporées, etc. pour la culture neutre. Le bloc de code contient uniquement le code d’application à utiliser par toutes les cultures prises en charge. Le Common Language Runtime prend en charge un modèle de ressource d’assembly satellite qui sépare le code exécutable d’une application de ses ressources. Pour plus d’informations sur l’implémentation de ce modèle, consultez Ressources dans .NET.
Pour chaque version localisée de votre application, ajoutez un nouvel assembly satellite qui contient le bloc d’interface utilisateur localisé traduit dans la langue appropriée pour la culture cible. Le bloc de code pour toutes les cultures doit rester le même. La combinaison d’une version localisée du bloc d’interface utilisateur avec le bloc de code produit une version localisée de votre application.
Dans cet article, vous apprendrez à utiliser les implémentations IStringLocalizer<T> et IStringLocalizerFactory. Tout le code source d'exemple dans cet article s'appuie sur les packages NuGet Microsoft.Extensions.Localization
et Microsoft.Extensions.Hosting
. Pour plus d’informations sur l’hébergement, consultez l’hôte générique .NET.
Fichiers de ressources
Le mécanisme principal pour isoler les chaînes localisables est avec les fichiers de ressources. Un fichier de ressources est un fichier XML avec l’extension de fichier .resx . Les fichiers de ressources sont traduits avant l’exécution de l’application consommatrice, en d’autres termes, ils représentent le contenu traduit au repos. Un nom de fichier de ressources contient généralement un identificateur de paramètres régionaux et prend la forme suivante :
<FullTypeName><.Locale>.resx
Où :
-
<FullTypeName>
représente les ressources localisables pour un type spécifique. - Le paramètre facultatif
<.Locale>
représente les paramètres régionaux du contenu du fichier de ressources.
Spécification des paramètres régionaux
Les paramètres régionaux doivent définir la langue, au minimum, mais elles peuvent également définir la culture (langue régionale) et même le pays ou la région. Ces segments sont généralement délimités par le -
caractère. Avec la spécificité supplémentaire d’une culture, les règles de « secours pour la culture » sont appliquées où les meilleures correspondances sont hiérarchisées. Les paramètres régionaux doivent être mappés à une balise de langue connue. Pour plus d’informations, consultez CultureInfo.Name.
Scénarios de repli culturels
Imagine que votre application localisée prend en charge différents paramètres régionaux serbe et dispose des fichiers de ressources suivants pour son MessageService
:
Fichier | Langue régionale | Code de pays |
---|---|---|
MessageService.sr-Cyrl-RS.resx | (Cyrillique, Serbie) | RS |
MessageService.sr-Cyrl.resx | Cyrillique | |
MessageService.sr-Latn-BA.resx | (Latin, Bosnie-et-Herzégovine) | BA |
MessageService.sr-Latn-ME.resx | (Latin, Monténégro) | moi |
MessageService.sr-Latn-RS.resx | (Latin, Serbie) | RS |
MessageService.sr-Latn.resx | Latin | |
MessageService.sr.resx | † Latin | |
MessageService.resx |
† Langue régionale par défaut pour la langue.
Lorsque votre application s’exécute avec le CultureInfo.CurrentCulture défini sur une culture de "sr-Cyrl-RS"
localisation tente de résoudre les fichiers dans l’ordre suivant :
- MessageService.sr-Cyrl-RS.resx
- MessageService.sr-Cyrl.resx
- MessageService.sr.resx
- MessageService.resx
Toutefois, si votre application s’exécutait avec le CultureInfo.CurrentCulture défini sur une culture de "sr-Latn-BA"
localisation tente de résoudre les fichiers dans l’ordre suivant :
- MessageService.sr-Latn-BA.resx
- MessageService.sr-Latn.resx
- MessageService.sr.resx
- MessageService.resx
La règle de « secours pour la culture » ignore les paramètres régionaux lorsqu’il n’existe aucune correspondance correspondante, ce qui signifie que le numéro de fichier de ressource quatre est sélectionné s’il ne parvient pas à trouver une correspondance. Si la culture était définie "fr-FR"
, la localisation finirait par dépendre du fichier MessageService.resx, ce qui peut être problématique. Pour plus d’informations, consultez la procédure de remplacement des ressources.
Recherche de ressources
Les fichiers de ressources sont automatiquement résolus dans le cadre d’une routine de recherche. Si le nom de fichier de votre projet est différent de l’espace de noms racine de votre projet, le nom de l’assembly peut différer. Cela peut empêcher la recherche de ressources d’être correctement effectuée. Pour résoudre cette incompatibilité, utilisez la RootNamespaceAttribute méthode pour fournir un indicateur aux services de localisation. Lorsqu’elle est fournie, elle est utilisée lors de la recherche de ressources.
L’exemple de projet est nommé example.csproj, qui crée une example.dll et example.exe, mais l’espace Localization.Example
de noms est utilisé. Appliquez un attribut de assembly
niveau pour corriger cette incompatibilité :
[assembly: RootNamespace("Localization.Example")]
Inscrire les services de localisation
Pour inscrire des services de localisation, appelez une des méthodes d’extension AddLocalization pendant la configuration des services. Cela permet l’injection de dépendances (DI) des types suivants :
- Microsoft.Extensions.Localization.IStringLocalizer<T>
- Microsoft.Extensions.Localization.IStringLocalizerFactory
Configurer les options de localisation
La surcharge AddLocalization(IServiceCollection, Action<LocalizationOptions>) accepte un paramètre setupAction
de type Action<LocalizationOptions>
. Cela vous permet de configurer les options de localisation.
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
});
// Omitted for brevity.
Les fichiers de ressources peuvent vivre n’importe où dans un projet, mais il existe des pratiques courantes en place qui se sont avérées réussies. Plus souvent que non, le chemin de la moindre résistance est suivi. Le code C# précédent :
- Crée le générateur d’application hôte par défaut.
- Appelle
AddLocalization
dans la collection de services en spécifiant LocalizationOptions.ResourcesPath en tant que"Resources"
.
Cela entraînerait la recherche par les services de localisation dans le répertoire Ressources pour les fichiers de ressources.
Utiliser IStringLocalizer<T>
et IStringLocalizerFactory
Une fois que vous avez inscrit (et éventuellement configuré) les services de localisation, vous pouvez utiliser les types suivants avec DI :
Pour créer un service de message capable de retourner des chaînes localisées, tenez compte des éléments suivants 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;
}
}
Dans le code C# précédent :
- Un
IStringLocalizer<MessageService> localizer
champ est déclaré. - Le constructeur principal définit un
IStringLocalizer<MessageService>
paramètre et le capture en tant qu’argumentlocalizer
. - La
GetGreetingMessage
méthode invoque le IStringLocalizer.Item[String] en passant"GreetingMessage"
en tant qu’argument.
Le IStringLocalizer
prend également en charge les ressources de chaîne paramétrables, considérez ce qui suit 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;
}
}
Dans le code C# précédent :
- Un
IStringLocalizer _localizer
champ est déclaré. - Le constructeur principal prend le paramètre
IStringLocalizerFactory
, utilisé pour créer unIStringLocalizer
à partir du typeParameterizedMessageService
et l'assigne au champ_localizer
. - La
GetFormattedMessage
méthode appelle IStringLocalizer.Item[String, Object[]], passe"DinnerPriceFormat"
, objetdateTime
etdinnerPrice
en tant qu’arguments.
Importante
Ce IStringLocalizerFactory
n’est pas obligatoire. Au lieu de cela, il est préférable que les services consommés nécessitent le IStringLocalizer<T>.
Les deux indexeurs IStringLocalizer.Item[] retournent un LocalizedString, qui a des conversions implicites en string?
.
Mets tout ensemble
Pour illustrer une application à l’aide des deux services de message, ainsi que des fichiers de localisation et de ressources, tenez compte du fichier Program.cs suivant :
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();
Dans le code C# précédent :
- Le RootNamespaceAttribute définit
"Localization.Example"
en tant qu’espace de noms racine. - La Console.OutputEncoding est affectée à Encoding.Unicode.
- Lorsque un seul argument est passé à
args
, CultureInfo.CurrentCulture et CultureInfo.CurrentUICulture reçoivent le résultat de CultureInfo.GetCultureInfo(String) donné pararg[0]
. - Le Host fichier est créé avec les valeurs par défaut.
- Les services de localisation,
MessageService
, etParameterizedMessageService
sont inscrits auprès deIServiceCollection
pour DI. - Pour éliminer les interférences, la journalisation est configurée pour ignorer tout niveau de journalisation inférieur à un avertissement.
- L’élément
MessageService
est résolu à partir de l’instanceIServiceProvider
et le message résultant est consigné. - Le
ParameterizedMessageService
est résolu à partir de l’instanceIServiceProvider
et son message mis en forme résultant est enregistré.
Chacune des *MessageService
classes définit un ensemble de fichiers .resx , chacun avec une entrée unique. Voici l’exemple de contenu des MessageService
fichiers de ressources, en commençant par MessageService.resx :
<?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>
Voici l’exemple de contenu des ParameterizedMessageService
fichiers de ressources, en commençant par ParameterizedMessageService.resx :
<?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>
Conseil / Astuce
Tous les commentaires XML du fichier de ressources, le schéma et les éléments <resheader>
sont intentionnellement omis par souci de concision.
Exemples d’exécutions
L’exemple d’exécution suivant montre les différentes sorties localisées, en fonction des paramètres régionaux ciblés.
Prenons l’exemple "sr-Latn"
suivant :
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 ¤.
Lors de l’omission d’un argument à l’interface CLI .NET pour exécuter le projet, la culture système par défaut est utilisée dans ce cas "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.
Lors de la transmission "sr-Cryl-RS"
, les fichiers de ressources correspondants corrects sont trouvés et la localisation appliquée :
dotnet run --project .\example\example.csproj sr-Cryl-RS
warn: Localization.Example[0]
Здраво пријатељи, ".NЕТ" девелопер заједница је узбуђена што вас види овде!
warn: Localization.Example[0]
У уторак, 03. август 2021. моја вечера је коштала 38 RSD.
L’exemple d’application ne fournit pas de fichiers de ressources pour "fr-CA"
, mais lorsqu’il est appelé avec cette culture, les fichiers de ressources non localisés sont utilisés.
Avertissement
Étant donné que la culture est trouvée, mais que les fichiers de ressources corrects ne le sont pas, lorsque la mise en forme est appliquée, cela aboutit à une localisation partielle.
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 $.