Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La localizzazione è il processo di conversione delle risorse di un'applicazione in versioni localizzate per ogni lingua supportata dall'applicazione. È consigliabile procedere al passaggio di localizzazione solo dopo aver completato il passaggio di revisione della localizzabilità per verificare che l'applicazione globalizzata sia pronta per la localizzazione.
Un'applicazione pronta per la localizzazione è separata in due blocchi concettuali: un blocco che contiene tutti gli elementi dell'interfaccia utente e un blocco che contiene codice eseguibile. Il blocco dell'interfaccia utente contiene solo elementi dell'interfaccia utente localizzabili, ad esempio stringhe, messaggi di errore, finestre di dialogo, menu, risorse di oggetti incorporate e così via per la cultura neutra. Il blocco di codice contiene solo il codice dell'applicazione da essere utilizzato da tutte le culture supportate. Il Common Language Runtime supporta un modello di risorse assembly satellite che separa il codice eseguibile di un'applicazione dalle sue risorse. Per altre informazioni sull'implementazione di questo modello, vedere Risorse in .NET.
Per ogni versione localizzata dell'applicazione, aggiungere un nuovo assembly satellite contenente il blocco dell'interfaccia utente per la versione localizzata tradotto nella lingua appropriata per la cultura di destinazione. Il blocco di codice per tutte le culture dovrebbe rimanere invariato. La combinazione di una versione localizzata del blocco dell'interfaccia utente con il blocco di codice produce una versione localizzata dell'applicazione.
In questo articolo, si apprenderà come utilizzare le implementazioni IStringLocalizer<T> e IStringLocalizerFactory. Tutto il codice sorgente di esempio in questo articolo si basa sui pacchetti NuGet Microsoft.Extensions.Localization
e Microsoft.Extensions.Hosting
. Per ulteriori informazioni sull'hosting, vedere Host Generico .NET.
File di risorse
Il meccanismo principale per isolare le stringhe localizzabili è costituito dai file di risorse. Un file di risorse è un file XML con estensione resx . I file di risorse vengono tradotti prima dell'esecuzione dell'applicazione che li utilizza, in altre parole, rappresentano il contenuto tradotto a riposo. Un nome di file di risorse contiene in genere un identificatore delle impostazioni locali e si presenta nel seguente modo:
<FullTypeName><.Locale>.resx
Dove:
- Il
<FullTypeName>
rappresenta le risorse localizzabili per un tipo specifico. - L'oggetto facoltativo
<.Locale>
rappresenta le impostazioni locali del contenuto del file di risorse.
Specificare le localizzazioni
L'impostazione locale deve definire la lingua, almeno come requisito minimo, ma può anche definire la cultura (lingua regionale) e persino il paese o la regione. Questi segmenti sono comunemente delimitati dal -
carattere . Con l'aggiunta della specificità di una cultura, vengono applicate le regole di fallback in cui le corrispondenze migliori sono prioritarie. Le località devono essere mappate a un tag di lingua conosciuto. Per altre informazioni, vedere CultureInfo.Name.
Scenari di fallback culturale
Immagina che la tua app localizzata supporti varie località serbe e abbia i seguenti file di risorse per il suo MessageService
.
Documento | Lingua regionale | Codice paese |
---|---|---|
MessageService.sr-Cyrl-RS.resx | (Cirillico, Serbia) | RS |
MessageService.sr-Cyrl.resx | Cirillico | |
MessageService.sr-Latn-BA.resx | (Alfabeto latino, Bosnia ed Erzegovina) | BA |
MessageService.sr-Latn-ME.resx | (Alfabeto latino, Montenegro) | me |
MessageService.sr-Latn-RS.resx | (Alfabeto latino, Serbia) | RS |
MessageService.sr-Latn.resx | Latino | |
MessageService.sr.resx | † Latino | |
MessageService.resx |
† Lingua regionale predefinita per la lingua.
Quando l'app è in esecuzione con l'opzione CultureInfo.CurrentCulture impostata su una cultura specifica di "sr-Cyrl-RS"
, la localizzazione tenta di risolvere i file nel seguente ordine:
- MessageService.sr-Cyrl-RS.resx
- MessageService.sr-Cyrl.resx
- MessageService.sr.resx
- MessageService.resx
Tuttavia, se l'app è in esecuzione con CultureInfo.CurrentCulture impostato sulla cultura "sr-Latn-BA"
, la localizzazione tenta di risolvere i file nel seguente ordine:
- MessageService.sr-Latn-BA.resx
- MessageService.sr-Latn.resx
- MessageService.sr.resx
- MessageService.resx
La regola di fallback della cultura ignorerà le impostazioni locali quando non sono presenti corrispondenze, questo significa che il quarto file di risorse viene selezionato se non è in grado di trovare una corrispondenza. Se le impostazioni cultura erano impostate su "fr-FR"
, la localizzazione finirebbe per cadere nel file MessageService.resx che può essere problematico. Per altre informazioni, vedere Processo di fallback delle risorse.
Ricerca risorse
I file di risorse vengono risolti automaticamente come parte di una routine di ricerca. Se il nome del file di progetto è diverso dallo spazio dei nomi radice del progetto, il nome dell'assembly potrebbe essere diverso. Questo può impedire che la ricerca delle risorse abbia successo. Per risolvere questa mancata corrispondenza, usa il RootNamespaceAttribute per fornire un suggerimento ai servizi di localizzazione. Se specificato, viene usato durante la ricerca delle risorse.
Il progetto di esempio è denominato example.csproj, che crea un example.dll e example.exe, ma viene usato lo Localization.Example
spazio dei nomi . Applicare un assembly
attributo di livello per correggere questa mancata corrispondenza:
[assembly: RootNamespace("Localization.Example")]
Registrare i servizi di localizzazione
Per registrare i servizi di localizzazione, chiamare uno dei AddLocalization metodi di estensione durante la configurazione dei servizi. Consentirà l'iniezione delle dipendenze (DI) per i seguenti tipi:
- Microsoft.Extensions.Localization.IStringLocalizer<T>
- Microsoft.Extensions.Localization.IStringLocalizerFactory
Configurare le opzioni di localizzazione
L'overload AddLocalization(IServiceCollection, Action<LocalizationOptions>) accetta un setupAction
parametro di tipo Action<LocalizationOptions>
. In questo modo è possibile configurare le opzioni di localizzazione.
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
});
// Omitted for brevity.
I file di risorse possono vivere ovunque in un progetto, ma esistono procedure comuni che hanno dimostrato di avere successo. Più spesso di non, viene seguita la via della minima resistenza. Il codice C# precedente:
- Crea il generatore di app host predefinito.
- Chiama
AddLocalization
nella raccolta di servizi, specificando LocalizationOptions.ResourcesPath come"Resources"
.
In questo modo i servizi di localizzazione cercherebbero nella directory Resources i file di risorse.
Usare IStringLocalizer<T>
ed IStringLocalizerFactory
Dopo aver registrato (e facoltativamente configurato) i servizi di localizzazione, è possibile usare i tipi seguenti con l'inserimento delle dipendenze:
Per creare un servizio messaggi in grado di restituire stringhe localizzate, considerare quanto segue 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;
}
}
Nel codice C# precedente:
- Viene dichiarato un
IStringLocalizer<MessageService> localizer
campo. - Il costruttore primario definisce un
IStringLocalizer<MessageService>
parametro e lo acquisisce comelocalizer
argomento. - Il metodo
GetGreetingMessage
invoca il IStringLocalizer.Item[String] passando"GreetingMessage"
come argomento.
Il IStringLocalizer
supporta anche le risorse stringa con parametri, considera quanto segue 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;
}
}
Nel codice C# precedente:
- Viene dichiarato un
IStringLocalizer _localizer
campo. - Il costruttore primario accetta un
IStringLocalizerFactory
parametro, che viene usato per creare unIStringLocalizer
oggetto dalParameterizedMessageService
tipo e lo assegna al_localizer
campo. - Il
GetFormattedMessage
metodo richiama IStringLocalizer.Item[String, Object[]], passando"DinnerPriceFormat"
, undateTime
oggetto edinnerPrice
come argomenti.
Importante
Non è obbligatorio IStringLocalizerFactory
. È preferibile che i servizi utilizzati richiedano il IStringLocalizer<T>.
Entrambi IStringLocalizer.Item[] gli indicizzatori restituiscono un LocalizedString, con conversioni implicite in string?
.
Combinare tutti gli elementi
Per esemplificare un'app usando entrambi i servizi di messaggistica, insieme alla localizzazione e ai file di risorse, considerare il file Program.cs seguente.
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();
Nel codice C# precedente:
-
RootNamespaceAttribute imposta
"Localization.Example"
come spazio dei nomi radice. - Il Console.OutputEncoding viene assegnato a Encoding.Unicode.
- Quando viene passato un singolo argomento a
args
, a CultureInfo.CurrentCulture e CultureInfo.CurrentUICulture viene assegnato il risultato di CultureInfo.GetCultureInfo(String) in base aarg[0]
. - Viene Host creato con predefiniti.
- I servizi di localizzazione,
MessageService
eParameterizedMessageService
vengono registrati nell'oggetto per l'inserimentoIServiceCollection
delle dipendenze. - Per rimuovere il rumore, la registrazione è configurata per ignorare qualsiasi livello di log inferiore a un avviso.
- L'istanza
MessageService
risolveIServiceProvider
e il messaggio risultante è registrato su registro. - L'oggetto
ParameterizedMessageService
viene risolto dall'istanzaIServiceProvider
e il messaggio formattato risultante viene registrato.
Ognuna delle *MessageService
classi definisce un set di file con estensione resx , ognuno con una singola voce. Ecco il contenuto di esempio per i file di MessageService
risorse, a partire da 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>
Ecco il contenuto di esempio per i file di ParameterizedMessageService
risorse, a partire da 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>
Suggerimento
Tutti i commenti, gli schemi e <resheader>
gli elementi XML del file di risorse vengono intenzionalmente omessi per brevità.
Esecuzioni di esempio
L'esempio seguente illustra i vari output localizzati, date le impostazioni locali di destinazione.
Prendere in considerazione "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 ¤.
Quando si omette un argomento alla CLI .NET per eseguire il progetto, viene utilizzata la cultura di sistema predefinita, in questo caso "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.
Quando si passa "sr-Cryl-RS"
, vengono trovati i file di risorse corrispondenti corretti e la localizzazione applicata.
dotnet run --project .\example\example.csproj sr-Cryl-RS
warn: Localization.Example[0]
Здраво пријатељи, ".NЕТ" девелопер заједница је узбуђена што вас види овде!
warn: Localization.Example[0]
У уторак, 03. август 2021. моја вечера је коштала 38 RSD.
L'applicazione di esempio non fornisce i file di risorse per "fr-CA"
, ma quando viene richiamata con quella cultura, vengono usati i file di risorse non localizzati.
Avvertimento
Poiché la cultura viene trovata ma i file di risorse corretti non sono trovati, quando viene applicata la formattazione, si ottiene una localizzazione parziale.
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 $.