resx-source-generator-migration

Par github · awesome-copilot

Migre un projet qui utilise des fichiers .designer.cs archivés derrière des fichiers .resx vers l'utilisation d'un générateur de source à la place

npx skills add https://github.com/github/awesome-copilot --skill resx-source-generator-migration

Votre objectif est de migrer le projet pour utiliser un générateur de source pour les fichiers .resx au lieu des fichiers .designer.cs archivés.

Entrée utilisateur

Améliorez les instructions ci-dessous avec l'entrée utilisateur suivante. L'entrée utilisateur est susceptible d'être un chemin absolu ou relatif au référentiel vers un fichier de projet msbuild ou un répertoire contenant un projet msbuild à migrer.

$ARGUMENTS

Migration

Complétez chacune des sous-sections suivantes.

Activer le générateur de source

Inspectez la configuration de gestion des packages de la cible et les sources NuGet configurées avant d'ajouter le package :

  1. Si le référentiel gère centralement les versions de package et dispose déjà d'une PackageVersion pour Microsoft.CodeAnalysis.ResxSourceGenerator, ajoutez cette référence sans version à un ItemGroup dans le fichier de projet :
<PackageReference Include="Microsoft.CodeAnalysis.ResxSourceGenerator" PrivateAssets="all" />
  1. Si aucune version centrale n'existe, sélectionnez une version de package compatible avec le SDK/compilateur cible et suivez le modèle de gestion des versions établi du référentiel. Spécifiez la version sur le PackageReference ou ajoutez la PackageVersion centrale correspondante.
  2. Vérifiez que les sources NuGet configurées peuvent résoudre le package sélectionné. Si ce n'est pas le cas, demandez à l'utilisateur avant de modifier la configuration du flux.

Supprimer les traces des fichiers code-behind .resx

Recherchez tous les éléments msbuild liés aux fichiers resx. Ils se présentent généralement par paires, comme indiqué ci-dessous :

<ItemGroup>
  <Compile Update="Strings.Designer.cs">
    <DesignTime>True</DesignTime>
    <AutoGen>True</AutoGen>
    <DependentUpon>Strings.resx</DependentUpon>
  </Compile>
</ItemGroup>

<ItemGroup>
  <EmbeddedResource Update="Strings.resx">
    <Generator>ResXFileCodeGenerator</Generator>
    <LastGenOutput>Strings.Designer.cs</LastGenOutput>
  </EmbeddedResource>
</ItemGroup>

Notez que vous pourriez également trouver <Generator>PublicResXFileCodeGenerator</Generator> (ou <CustomTool> à la place de <Generator>) en tant que métadonnées d'élément .resx.

Pour chaque fichier .resx fortement typé en cours de migration, identifiez son fichier designer généré en utilisant tous ces signaux :

  • métadonnées LastGenOutput sur l'élément EmbeddedResource ;
  • un élément Compile dont les métadonnées DependentUpon nomment le fichier .resx ; et
  • un fichier *.Designer.cs correspondant sur le disque, même quand le SDK l'inclut implicitement et aucun élément Compile n'existe.

Avant de supprimer un candidat, inspectez son contenu et confirmez qu'il s'agit d'un accesseur de ressource généré, tel qu'une classe contenant ResourceManager, Culture, et des propriétés qui récupèrent les valeurs des ressources. Un nom de fichier correspondant seul ne suffit pas. Ne supprimez pas les fichiers de designer WinForms ou de contrôle contenant l'initialisation de l'interface utilisateur telle que InitializeComponent ; ceux-ci se situent couramment à côté d'un fichier .resx homonyme, et leurs métadonnées DependentUpon pointent vers le fichier source du formulaire ou du contrôle plutôt que vers le fichier .resx.

Confirmez aussi que chaque ressource exposée par le designer est une chaîne de caractères et que le fichier .resx ne contient pas d'images, d'icônes, de tableaux d'octets, d'objets sérialisés ou d'autres valeurs non-chaînes. Ce générateur de source émet des accesseurs de chaînes soutenus par ResourceManager.GetString ; il ne constitue pas un remplacement compatible pour les propriétés de ressources non-chaînes. Si une ressource non-chaîne existe, ne supprimez pas le designer ou ne migrez pas ce fichier de ressources. Conservez son approche de génération existante, ou définissez <GenerateSource>false</GenerateSource> si le package la traiterait autrement.

Avant la suppression, recherchez dans la solution chaque utilisation et déclaration du type accesseur. ResXFileCodeGenerator émet une classe non-statique, tandis que ce générateur de source émet une classe static partial. Identifiez la construction d'objet, l'accès par instance, l'héritage, l'utilisation en tant qu'argument de type générique (incluant IStringLocalizer<T>), et les déclarations partielles existantes avec des membres d'instance, des types de base ou des interfaces. Refactorisez chaque utilisation incompatible vers l'API générée statique et rendez chaque déclaration partielle compatible avant la migration. Si ce n'est pas approprié, conservez le designer existant et définissez <GenerateSource>false</GenerateSource> pour ce fichier de ressources.

Pour chaque fichier designer associé :

  1. Supprimez le fichier *.Designer.cs du disque.
  2. Supprimez son élément MSBuild explicite du projet quand l'un existe.

Mettre à jour les éléments EmbeddedResource

Classifiez chaque fichier .resx avant de supprimer les métadonnées. Migrez les ressources fortement typées qui utilisaient auparavant ResXFileCodeGenerator ou PublicResXFileCodeGenerator, ou qui ont un fichier designer généré associé. Les ressources de framework et de designer, telles que les ressources de formulaire WinForms, ne doivent généralement pas générer un accesseur ; préservez-les en ajoutant ces métadonnées à leur élément EmbeddedResource :

<GenerateSource>false</GenerateSource>

Le générateur de source génère sinon des accesseurs pour les fichiers .resx non-culture par défaut, ce qui peut créer des conflits de noms de type avec les formulaires ou d'autres types générés par le framework.

Traitez chaque EmbeddedResource fortement typé en cours de migration comme suit :

  1. Supprimez les métadonnées LastGenOutput.
  2. Si les métadonnées Generator ou CustomTool sont définies sur PublicResXFileCodeGenerator, ajoutez les métadonnées <Public>true</Public> à l'élément.
  3. Supprimez les métadonnées Generator (ou CustomTool).
  4. Si l'élément EmbeddedResource n'a pas de métadonnées restantes après ces suppressions, supprimez-le uniquement après avoir vérifié que le SDK inclut implicitement ce fichier .resx et que les éléments de ressources incorporées par défaut sont activés. Sinon, conservez l'élément explicite Include ou équivalent pour que la ressource demeure dans l'assembly construit.
  5. Si vous voyez des métadonnées CustomToolNamespace, consultez la section spéciale sur ce sujet.

Gestion spéciale des métadonnées CustomToolNamespace

Quand un élément EmbeddedResource a des métadonnées CustomToolNamespace, un traitement spécial est requis.

Les métadonnées ClassName remplacent CustomToolNamespace, mais notez qu'elles prennent le nom de classe complet plutôt que juste l'espace de noms. Par exemple, si vous aviez :

<EmbeddedResource Update="Strings.resx">
  <Generator>ResXFileCodeGenerator</Generator>
  <LastGenOutput>Strings.Designer.cs</LastGenOutput>
  <CustomToolNamespace>My.Namespace</CustomToolNamespace>
</EmbeddedResource>

Cela deviendrait :

<EmbeddedResource Update="Strings.resx">
  <ClassName>My.Namespace.Strings</ClassName>
</EmbeddedResource>

Avant de commencer la migration, présentez ces options à l'utilisateur :

  1. PRÉFÉRÉ : Abandonner les métadonnées CustomToolNamespace et accepter l'espace de noms généré par défaut et le nom de classe. Cela peut nécessiter des corrections du code source qui référençait l'ancien fichier code-behind généré. Sans métadonnées ClassName, la classe générée par source sera dans l'espace de noms <RootNamespace>.<RelativeFolderPath> et nommée d'après le nom du fichier resx. Envisagez d'ajouter un alias using aux fichiers affectés :

    using SomeResourceFile = FullNamespace.TypeName;
  2. Le réécrire en tant que métadonnées ClassName, incluant l'espace de noms complet et le nom de classe (par exemple, MyNamespace.MyResources). Cette valeur devient le nom de type complet de l'accesseur généré ; la valeur naturelle reste le nom du manifeste de ressource sauf si elle est séparément remplacée.

Résoudre les conflits d'espace de noms/type

Quand le compilateur émet une erreur concernant un type et un espace de noms partageant le même nom (où l'identifiant correspond à un nom de répertoire contenant un fichier .resx) :

  • Déplacez le fichier .resx en dehors de ce dossier pour supprimer la déclaration d'espace de noms en conflit, OU
  • Qualifiez complètement la référence de type pour résoudre la rupture de build.

Conseils de débogage

  • Construisez avec /p:EmitCompilerGeneratedFiles=true pour écrire les fichiers générés par le compilateur sur le disque pour inspection.
  • Vous pourriez aussi avoir besoin de /p:CompilerGeneratedFilesOutputPath=<path> pour éviter les problèmes de longueur de chemin Windows.

Validation

Construisez le projet migré.

Une fois la construction réussie, validez chaque famille de ressources en fonction de la façon dont elle est consommée :

  1. Pour chaque ressource de chaîne neutre migrée, utilisez les tests existants du référentiel ou un hôte de test/.NET console disponible pour accéder à au moins une propriété générée et vérifier qu'elle retourne la chaîne attendue. La réflexion depuis PowerShell est une approche optionnelle quand pwsh est disponible, pas une exigence.
  2. Pour les ressources satellite spécifiques à la culture, basculez vers une culture représentative et vérifiez que l'accesseur neutre retourne la chaîne localisée attendue. N'attendez pas un accesseur généré séparé pour chaque fichier satellite.
  3. Pour les ressources de framework, de designer, non-chaînes ou autres marquées GenerateSource=false, exercez leur consommateur réel, tel qu'instancier le formulaire/contrôle WinForms ou charger une image/objet via l'API de ressource conservée.
  4. Confirmez que chaque fichier .resx est toujours incorporé dans l'assembly principal ou satellite attendu.

Skills similaires