Remarque
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.
Les applications s’appuient sur le Gestionnaire de ressources .NET Framework, représenté par la ResourceManager classe, pour récupérer des ressources localisées. Resource Manager suppose qu’un modèle hub-and-spoke est utilisé pour empaqueter et déployer des ressources. Le hub est l’assembly principal qui contient le code exécutable non localisable et les ressources d’une seule culture, appelée culture neutre ou par défaut. La culture par défaut est la culture de secours pour l’application ; il s’agit de la culture dont les ressources sont utilisées si des ressources localisées sont introuvables. Chaque spoke se connecte à un assembly satellite qui contient les ressources d’une culture unique, mais ne contient pas de code.
Ce modèle présente plusieurs avantages :
- Vous pouvez ajouter de manière incrémentielle des ressources pour de nouvelles cultures après avoir déployé une application. Étant donné que le développement ultérieur de ressources spécifiques à la culture peut nécessiter un temps important, cela vous permet de libérer d’abord votre application principale et de fournir des ressources spécifiques à la culture à une date ultérieure.
- Vous pouvez mettre à jour et modifier les assemblys satellites d’une application sans recompiler l’application.
- Une application doit charger uniquement les assemblys satellites qui contiennent les ressources nécessaires à une culture particulière. Cela peut réduire considérablement l’utilisation des ressources système.
Toutefois, il existe également des inconvénients pour ce modèle :
- Vous devez gérer plusieurs ensembles de ressources.
- Le coût initial du test d’une application augmente, car vous devez tester plusieurs configurations. Notez qu’à long terme, il sera plus facile et moins coûteux de tester une application principale avec plusieurs satellites, que de tester et de maintenir plusieurs versions internationales parallèles.
Conventions de nommage des ressources
Lorsque vous empaquetez les ressources de votre application, vous devez les nommer à l’aide des conventions d’affectation de noms des ressources attendues par le Common Language Runtime. Le runtime identifie une ressource par son nom de culture. Chaque culture reçoit un nom unique, qui est généralement une combinaison d’un nom de culture à deux lettres, minuscules associé à une langue et, si nécessaire, un nom de sous-culture à deux lettres, majuscules associé à un pays ou une région. Le nom de la sous-culture suit le nom de la culture, séparé par un tiret (-). Les exemples incluent ja-JP pour le japonais comme parlé au Japon, en-US pour l’anglais comme parlé aux États-Unis, de-DE pour l’allemand comme parlé en Allemagne ou de-AT pour l’allemand comme parlé en Autriche. Consultez la colonne Balise de langue dans la liste des noms de langue/région pris en charge par Windows. Les noms de culture suivent la norme définie par BCP 47.
Remarque
Il existe certaines exceptions pour les noms de culture à deux lettres, comme zh-Hans pour le chinois (simplifié).
Pour plus d’informations, consultez Créer des fichiers de ressources et créer des assemblys satellites.
Processus de repli des ressources
Le modèle Hub and Spoke pour l’empaquetage et le déploiement de ressources utilise un processus de secours pour localiser les ressources appropriées. Si une application demande une ressource localisée qui n’est pas disponible, le Common Language Runtime recherche dans la hiérarchie des cultures une ressource de secours appropriée qui correspond le plus étroitement à la demande de l’application de l’utilisateur et lève une exception uniquement en dernier recours. À chaque niveau de la hiérarchie, si une ressource appropriée est trouvée, le runtime l’utilise. Si la ressource est introuvable, la recherche se poursuit au niveau suivant.
Pour améliorer les performances de recherche, appliquez l’attribut NeutralResourcesLanguageAttribute à votre assembly principal et transmettez-le le nom du langage neutre qui fonctionnera avec votre assembly principal.
Processus de secours pour les ressources .NET Framework
Le processus de secours pour les ressources .NET Framework comprend les étapes suivantes :
Conseil / Astuce
Vous pouvez peut-être utiliser l’élément de configuration <relativeBindForResources> pour optimiser le processus de secours pour les ressources et le processus selon lequel le runtime recherche des assemblys de ressources. Pour plus d’informations, consultez Optimisation du processus de secours pour les ressources.
Le runtime vérifie d’abord le Global Assembly Cache pour un assembly qui correspond à la culture demandée pour votre application.
Le Global Assembly Cache peut stocker des assemblys de ressources partagés par de nombreuses applications. Cela vous libère de l'obligation d'inclure des ensembles de ressources spécifiques dans la structure de répertoires de chaque application que vous créez. Si le runtime trouve une référence à l’assembly, il recherche l’assembly pour la ressource demandée. S’il trouve l’entrée dans l’assemblage, il utilise la ressource demandée. S’il ne trouve pas l’entrée, il poursuit la recherche.
Le runtime vérifie ensuite le répertoire de l’assembly en cours d’exécution pour un sous-répertoire qui correspond à la culture demandée. S’il le trouve, il y recherche un assembly satellite valide pour la culture demandée. Le runtime recherche ensuite dans l'assemblage satellite la ressource demandée. S'il trouve la ressource dans l'assemblage, il l'utilise. S’il ne trouve pas la ressource, il poursuit la recherche.
Le runtime interroge ensuite Windows Installer pour déterminer si l’assembly satellite doit être installé à la demande. Dans ce cas, il gère l’installation, charge l’assembly et y recherche la ressource demandée. S'il trouve la ressource dans l'assemblage, il l'utilise. S’il ne trouve pas la ressource, il poursuit la recherche.
Le runtime déclenche l’événement AppDomain.AssemblyResolve pour indiquer qu’il lui est impossible de trouver l’assembly satellite. Si vous choisissez de gérer l’événement, votre gestionnaire d’événements peut renvoyer une référence à l’assembly satellite dont les ressources seront utilisées pour la recherche. Sinon, le gestionnaire d’événements retourne
nullet la recherche continue.Le runtime effectue ensuite une nouvelle recherche dans le Global Assembly Cache, cette fois pour trouver l’assembly parent de la culture demandée. Si l’assembly parent existe dans le Global Assembly Cache, le runtime recherche l’assembly pour la ressource demandée.
La culture parente est définie comme culture de secours appropriée. Considérez les parents comme candidats de secours, car la fourniture d’une ressource est préférable à la levée d’une exception. Ce processus vous permet également de réutiliser des ressources. Vous devez inclure une ressource particulière au niveau parent uniquement si la culture enfant n’a pas besoin de localiser la ressource demandée. Par exemple, si vous fournissez des assemblys satellites pour
en(anglais neutre),en-GB(anglais comme parlé au Royaume-Uni) eten-US(anglais comme parlé aux États-Unis), leensatellite contiendrait la terminologie commune, et lesen-GBen-USsatellites pourraient fournir des remplacements pour seulement ces termes qui diffèrent.Le runtime vérifie ensuite le répertoire de l’assembly en cours d’exécution pour voir s’il contient un répertoire parent. Si un répertoire parent existe, le runtime y recherche un assembly satellite valide pour la culture parente. S’il trouve l’assembly, le runtime recherche l’assembly pour la ressource demandée. S’il trouve la ressource, elle l’utilise. S’il ne trouve pas la ressource, il poursuit la recherche.
Le runtime interroge ensuite Windows Installer pour déterminer si l’assembly satellite parent doit être installé à la demande. Dans ce cas, il gère l’installation, charge l’assembly et y recherche la ressource demandée. S'il trouve la ressource dans l'assemblage, il l'utilise. S’il ne trouve pas la ressource, il poursuit la recherche.
Le runtime déclenche l’événement AppDomain.AssemblyResolve pour indiquer qu’il n’est pas en mesure de trouver une ressource de secours appropriée. Si vous choisissez de gérer l’événement, votre gestionnaire d’événements peut renvoyer une référence à l’assembly satellite dont les ressources seront utilisées pour la recherche. Sinon, le gestionnaire d’événements retourne
nullet la recherche continue.Le runtime recherche ensuite les assemblages parents, comme dans les trois étapes précédentes, à travers plusieurs niveaux possibles. Chaque culture n’a qu’un seul parent, qui est défini par la CultureInfo.Parent propriété, mais un parent peut avoir son propre parent. La recherche des cultures parentes s’arrête quand la propriété Parent d’une culture retourne CultureInfo.InvariantCulture ; pour la culture de secours pour les ressources, la culture indifférente n’est pas considérée comme une culture parente ou une culture qui peut avoir des ressources.
Si la culture spécifiée à l'origine ainsi que toutes les cultures parentes ont été recherchées et que la ressource reste introuvable, la ressource pour la culture de repli par défaut est utilisée. En règle générale, les ressources de la culture par défaut sont incluses dans l’assembly d’application principal. Toutefois, vous pouvez spécifier une valeur de Satellite pour la propriété Location de l’attribut NeutralResourcesLanguageAttribute pour indiquer que l’emplacement de secours ultime pour les ressources est un assemblage satellite, plutôt que l’assemblage principal.
Remarque
La ressource par défaut est la seule ressource qui peut être compilée avec l’assembly principal. Sauf si vous spécifiez un assembly satellite à l’aide de l’attribut NeutralResourcesLanguageAttribute, il s’agit du secours ultime (parent final). Par conséquent, nous vous recommandons d’inclure toujours un ensemble de ressources par défaut dans votre assembly principal. Cela aide à empêcher la levée d’exceptions. En incluant une ressource par défaut, vous fournissez un secours pour toutes les ressources et assurez-vous qu’au moins une ressource est toujours présente pour l’utilisateur, même si elle n’est pas spécifique à la culture.
Enfin, si le runtime ne trouve pas une ressource pour une culture par défaut (de secours), une exception MissingManifestResourceException ou MissingSatelliteAssemblyException est levée pour indiquer que la ressource est introuvable.
Par exemple, supposons que l’application demande une ressource localisée pour l’espagnol (Mexique) (la es-MX culture). Le runtime recherche d’abord le Global Assembly Cache pour l’assembly qui correspond es-MX, mais ne le trouve pas. Le runtime recherche ensuite le répertoire de l'assembly en cours d'exécution à la recherche d'un répertoire es-MX. En cas d’échec, il effectue une nouvelle recherche dans le Global Assembly Cache pour trouver un assembly parent qui reflète la culture de secours correspondante, ici es (espagnol). Si l’assembly parent est introuvable, le runtime recherche tous les niveaux potentiels d’assemblys parents pour la es-MX culture jusqu’à ce qu’il trouve une ressource correspondante. Si une ressource est introuvable, le runtime utilise la ressource pour la culture par défaut.
Optimiser le processus de repli des ressources du .NET Framework
Dans les conditions suivantes, vous pouvez optimiser le processus par lequel le runtime recherche des ressources dans les assemblys satellites :
Les assemblages satellites sont déployés au même emplacement que l'assemblage de code. Si l’assembly de code est installé dans le Global Assembly Cache, les assemblys satellites sont également installés dans le Global Assembly Cache. Si l’assemblage de code est installé dans un répertoire, les assemblages satellites sont installés dans des dossiers spécifiques à la culture de ce répertoire.
Les assemblies satellites ne sont pas installées sur demande.
Le code d’application ne gère pas l’événement AppDomain.AssemblyResolve .
Vous optimisez la sonde pour les assemblys satellites en incluant l’élément <relativeBindForResources> et en définissant son enabled attribut true dans le fichier de configuration de l’application, comme illustré dans l’exemple suivant.
<configuration>
<runtime>
<relativeBindForResources enabled="true" />
</runtime>
</configuration>
La sonde optimisée pour les ensembles satellites est une fonctionnalité activable. Autrement dit, le runtime suit les étapes décrites dans le processus de secours des ressources, sauf si l’élément <relativeBindForResources> est présent dans le fichier de configuration de l’application et que son enabled attribut est défini sur true. Si c’est le cas, le processus de détection d’un assembly satellite est modifié comme suit :
Le runtime utilise l’emplacement de l’assembly de code parent pour rechercher l’assembly satellite. Si l’assembly parent est installé dans le Global Assembly Cache, le runtime sonde dans le cache, mais pas dans le répertoire de l’application. Si l’assembly parent est installé dans un répertoire d’application, le runtime sonde dans le répertoire de l’application, mais pas dans le Global Assembly Cache.
Le runtime n’interroge pas Windows Installer pour l’installation à la demande d’assemblages satellites.
Si la sonde d’un assembly de ressources particulier échoue, le runtime ne déclenche pas l’événement AppDomain.AssemblyResolve .
Processus de repli des ressources .NET Core
Le processus de secours pour les ressources .NET Core comprend les étapes suivantes :
Le runtime tente de charger un assembly satellite pour la culture demandée.
Il recherche un sous-répertoire correspondant à la culture demandée dans le répertoire de l’assembly en cours d’exécution. S’il le trouve, il y recherche un assembly satellite valide pour la culture demandée et le charge.
Remarque
Sur les systèmes d’exploitation dont le système de fichiers respecte la casse (autrement dit, Linux et macOS), la recherche d’un sous-répertoire du nom de la culture est sensible à la casse. Le nom du sous-répertoire doit correspondre exactement au cas du CultureInfo.Name (par exemple,
esoues-MX).Remarque
Si le programmeur a dérivé un contexte de chargement d’assembly personnalisé à partir de AssemblyLoadContext, la situation se complique. Si l’assembly en cours d’exécution a été chargé dans le contexte personnalisé, le runtime charge l’assembly satellite dans le contexte personnalisé. Les détails sont hors de portée pour ce document. Voir AssemblyLoadContext.
Si un assemblage satellite n’a pas été trouvé, le AssemblyLoadContext déclenche l’événement AssemblyLoadContext.Resolving pour indiquer qu’il n’est pas en mesure de trouver l’assemblage satellite. Si vous choisissez de gérer l’événement, votre gestionnaire d’événements peut charger et renvoyer une référence à l’assembly satellite.
Si un assembly satellite n’a toujours pas été trouvé, AssemblyLoadContext déclenche l’événement AppDomain AppDomain.AssemblyResolve pour indiquer qu’il n’est pas en mesure de trouver l’assembly satellite. Si vous choisissez de gérer l’événement, votre gestionnaire d’événements peut charger et renvoyer une référence à l’assembly satellite.
Dès qu’il trouve un assembly satellite, le runtime y recherche la ressource demandée. S'il trouve la ressource dans l'assemblage, il l'utilise. S’il ne trouve pas la ressource, il poursuit la recherche.
Remarque
Pour trouver une ressource dans l’assembly satellite, le runtime recherche le fichier de ressources demandé par ResourceManager pour CultureInfo.Name. Dans le fichier de ressources, il recherche le nom de la ressource demandé. Si l’un des deux est introuvable, la ressource est traitée comme introuvable.
Le runtime parcourt ensuite les assemblys de culture parente à différents niveaux potentiels, en répétant à chaque fois les étapes 1 & 2.
La culture parente est définie comme une culture de secours appropriée. Considérez les parents comme candidats de secours, car la fourniture d’une ressource est préférable à la levée d’une exception. Ce processus vous permet également de réutiliser des ressources. Vous devez inclure une ressource particulière au niveau parent uniquement si la culture enfant n’a pas besoin de localiser la ressource demandée. Par exemple, si vous fournissez des assemblys satellites pour
en(anglais neutre),en-GB(anglais comme parlé au Royaume-Uni) eten-US(anglais comme parlé aux États-Unis), leensatellite contient la terminologie commune, et lesen-GBen-USsatellites fournissent des remplacements uniquement pour ces termes qui diffèrent.Chaque culture n’a qu’un seul parent, qui est défini par la CultureInfo.Parent propriété, mais un parent peut avoir son propre parent. La recherche des cultures parentes s’arrête lorsque la propriété Parent d’une culture retourne CultureInfo.InvariantCulture. Pour la récupération des ressources, la culture invariante n’est pas considérée comme une culture parente ni comme une culture pouvant avoir des ressources.
Si la culture spécifiée à l'origine ainsi que toutes les cultures parentes ont été recherchées et que la ressource reste introuvable, la ressource pour la culture de repli par défaut est utilisée. En règle générale, les ressources de la culture par défaut sont incluses dans l’assembly d’application principal. Toutefois, vous pouvez spécifier une valeur de Satellite pour la propriété Location afin d’indiquer que l’emplacement de secours ultime pour les ressources est un assembly satellite plutôt que l’assembly principal.
Remarque
La ressource par défaut est la seule ressource qui peut être compilée avec l’assembly principal. Sauf si vous spécifiez un assembly satellite à l’aide de l’attribut NeutralResourcesLanguageAttribute, il s’agit du secours ultime (parent final). Par conséquent, nous vous recommandons d’inclure toujours un ensemble de ressources par défaut dans votre assembly principal. Cela aide à empêcher la levée d’exceptions. En incluant un fichier de ressources par défaut, vous fournissez un secours pour toutes les ressources et assurez-vous qu’au moins une ressource est toujours présente pour l’utilisateur, même si elle n’est pas spécifique à la culture.
Enfin, si le runtime ne trouve pas de fichier de ressources pour une culture (de secours) par défaut, une exception MissingManifestResourceException ou MissingSatelliteAssemblyException est levée pour indiquer que la ressource est introuvable. Si le fichier de ressources est trouvé, mais que la ressource demandée n’est pas présente, la requête retourne
null.
Recours ultime à l'assemblage satellite
Vous pouvez éventuellement supprimer des ressources de l’assembly principal et spécifier que le runtime doit charger les ressources de secours ultimes d’un assembly satellite qui correspond à une culture spécifique. Pour contrôler le processus de secours, vous utilisez le NeutralResourcesLanguageAttribute(String, UltimateResourceFallbackLocation) constructeur et fournissez une valeur pour le UltimateResourceFallbackLocation paramètre qui spécifie si Resource Manager doit extraire les ressources de secours de l’assembly principal ou d’un assembly satellite.
L’exemple .NET Framework suivant utilise l’attribut NeutralResourcesLanguageAttribute pour stocker les ressources de secours d’une application dans un assembly satellite pour la langue française (fr). L’exemple contient deux fichiers de ressources textuels qui définissent une ressource de chaîne unique nommée Greeting. Le premier, resources.fr.txt, contient une ressource de langue française.
Greeting=Bon jour!
Le deuxième, ressources,ru.txt, contient une ressource de langue russe.
Greeting=Добрый день
Ces deux fichiers sont compilés en fichiers .resources en exécutant Resource File Generator (resgen.exe) à partir de la ligne de commande. Pour la ressource de langue française, la commande est :
resgen.exe resources.fr.txt
Pour la ressource de langue russe, la commande est :
resgen.exe resources.ru.txt
Les fichiers .resources sont incorporés dans des bibliothèques de liens dynamiques en exécutant Assembly Linker (al.exe) à partir de la ligne de commande de la ressource de langue française comme suit :
al /t:lib /embed:resources.fr.resources /culture:fr /out:fr\Example1.resources.dll
et pour la ressource de langue russe comme suit :
al /t:lib /embed:resources.ru.resources /culture:ru /out:ru\Example1.resources.dll
Le code source de l’application réside dans un fichier nommé Example1.cs ou Example1.vb. Il inclut l’attribut NeutralResourcesLanguageAttribute pour indiquer que la ressource d’application par défaut se trouve dans le sous-répertoire fr. Il instancie Resource Manager, récupère la valeur de la Greeting ressource et l’affiche à la console.
using System;
using System.Reflection;
using System.Resources;
[assembly:NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)]
public class Example
{
public static void Main()
{
ResourceManager rm = new ResourceManager("resources",
typeof(Example).Assembly);
string greeting = rm.GetString("Greeting");
Console.WriteLine(greeting);
}
}
Imports System.Reflection
Imports System.Resources
<Assembly: NeutralResourcesLanguage("fr", UltimateResourceFallbackLocation.Satellite)>
Module Example
Public Sub Main()
Dim rm As New ResourceManager("resources", GetType(Example).Assembly)
Dim greeting As String = rm.GetString("Greeting")
Console.WriteLine(greeting)
End Sub
End Module
Vous pouvez ensuite compiler le code source C# à partir de la ligne de commande comme suit :
csc Example1.cs
La commande du compilateur Visual Basic est très similaire :
vbc Example1.vb
Étant donné qu’il n’existe aucune ressource incorporée dans l’assembly principal, vous n’avez pas besoin de compiler à l’aide du /resource commutateur.
Lorsque vous exécutez l’exemple à partir d’un système dont la langue est autre que russe, elle affiche la sortie suivante :
Bon jour!
Alternative d’empaquetage suggérée
Les contraintes de temps ou de budget peuvent vous empêcher de créer un ensemble de ressources pour chaque sous-culture prise en charge par votre application. Au lieu de cela, vous pouvez créer un assemblage satellite unique pour une culture parente que toutes les sous-cultures associées peuvent utiliser. Par exemple, vous pouvez fournir un seul assembly satellite anglais (en) récupéré par les utilisateurs qui demandent des ressources anglaises spécifiques à une région et un seul assembly satellite allemand (de) pour les utilisateurs qui demandent des ressources allemandes spécifiques à la région. Par exemple, les demandes pour l’allemand tel qu’il est parlé en Allemagne (de-DE), en Autriche (de-AT) et en Suisse (de-CH) reviennent à l’assembly satellite allemand (de). Les ressources par défaut sont le dernier secours et doivent donc être les ressources qui seront demandées par la majorité des utilisateurs de votre application. Choisissez donc attentivement ces ressources. Cette approche déploie des ressources moins spécifiques à la culture, mais peut réduire considérablement les coûts de localisation de votre application.