Partager via


Prise en charge de plusieurs versions de .NET

De nombreuses bibliothèques ciblent une version spécifique du .NET Framework. Par exemple, vous pouvez avoir une version de votre bibliothèque spécifique à UWP et une autre version qui tire parti des fonctionnalités dans .NET Framework 4.6. Pour ce faire, NuGet prend en charge la mise en place de plusieurs versions de la même bibliothèque dans un package unique.

Cet article décrit la disposition d’un package NuGet, quelle que soit la façon dont le package ou les assemblys sont générés (autrement dit, la disposition est la même que l’utilisation de plusieurs fichiers .csproj de style non SDK et d’un fichier .nuspec personnalisé ou d’un seul style SDK multi-ciblé .csproj). Pour un projet de style SDK, les cibles du pack NuGet savent comment le package doit être disposé et automatisent la mise en place des assemblies dans les dossiers lib appropriés, ainsi que la création de groupes de dépendances pour chaque framework cible (TFM). Pour obtenir des instructions détaillées, consultez Prendre en charge plusieurs versions de .NET Framework dans votre fichier projet.

Vous devez disposer manuellement le package comme décrit dans cet article lors de l’utilisation de la méthode de répertoire de travail basée sur une convention décrite dans Création d’un package. Pour un projet de style SDK, la méthode automatisée est recommandée, mais vous pouvez également choisir de disposer manuellement le package comme décrit dans cet article.

Structure de dossiers de version du framework

Lors de la création d’un package qui contient une seule version d'une librairie ou qui cible individuellement plusieurs frameworks, vous créez toujours des sous-dossiers sous lib en utilisant des noms de framework avec la casse respectée selon la convention suivante :

lib\{framework name}[{version}]

Pour obtenir la liste complète des noms pris en charge, consultez la référence des frameworks cibles.

Vous ne devez jamais avoir une version de la bibliothèque qui n’est pas spécifique à une infrastructure et placée directement dans le dossier racine lib . (Cette fonctionnalité a été prise en charge uniquement avec packages.config). Cela rendait la bibliothèque compatible avec n’importe quel framework cible et l’autoriserait à être installée n’importe où, ce qui entraînerait probablement des erreurs d’exécution inattendues. L’ajout d’assemblys dans le dossier racine (par exemple lib\abc.dll) ou les sous-dossiers (par exemple lib\abc\abc.dll) a été déconseillé et est ignoré lors de l’utilisation du format PackagesReference.

Par exemple, la structure de dossiers suivante prend en charge quatre versions d’un assembly spécifiques à l’infrastructure :

\lib
    \net46
        \MyAssembly.dll
    \net461
        \MyAssembly.dll
    \uap
        \MyAssembly.dll
    \netcore
        \MyAssembly.dll

Pour inclure facilement tous ces fichiers lors de la génération du package, utilisez un caractère générique récursif ** dans la <files> section de votre .nuspec:

<files>
    <file src="lib\**" target="lib/{framework name}[{version}]" />
</files>

Dossiers spécifiques à l’architecture

Si vous avez des assemblys spécifiques à l’architecture, c’est-à-dire des assemblys distincts qui ciblent ARM, x86 et x64, vous devez les placer dans un dossier nommé runtimes dans les sous-dossiers nommés {platform}-{architecture}\lib\{framework} ou {platform}-{architecture}\native. Par exemple, la structure de dossiers suivante prend en charge les DLL natives et managées ciblant Windows 10 et l’infrastructure uap10.0 :

\runtimes
    \win10-arm
        \native
        \lib\uap10.0
    \win10-x86
        \native
        \lib\uap10.0
    \win10-x64
        \native
        \lib\uap10.0

Ces assemblages ne seront disponibles qu’au moment de l’exécution. Par conséquent, si vous souhaitez également fournir l’assemblage pour la compilation, assurez-vous qu’il se trouve dans le dossier /ref/{tfm}.

Notez que NuGet sélectionne toujours ces ressources de compilation ou d'exécution à partir d'un seul dossier. Ainsi, si certaines ressources compatibles proviennent de /ref, celles de /lib seront ignorées pour ajouter des assemblys de compilation. De même, si certaines ressources compatibles proviennent de /runtimes, alors /lib sera également ignoré pendant l'exécution.

Consultez Créer des packages UWP pour obtenir un exemple de référencement de ces fichiers dans le .nuspec manifeste.

En outre, voir Empaquetage d’un composant d’application du Windows Store avec NuGet

Ajustement des versions d’assemblage et du framework cible dans un projet

Lorsque NuGet installe un package qui a plusieurs versions d’assembly, il tente de faire correspondre le nom de l’infrastructure de l’assembly à l’infrastructure cible du projet.

Si une correspondance est introuvable, NuGet copie l’assembly pour la version la plus élevée qui est inférieure ou égale à l’infrastructure cible du projet, le cas échéant. Si aucun assembly compatible n’est trouvé, NuGet retourne un message d’erreur approprié.

Par exemple, considérez la structure de dossiers suivante dans un package :

\lib
    \net45
        \MyAssembly.dll
    \net461
        \MyAssembly.dll

Lors de l’installation de ce package dans un projet qui cible .NET Framework 4.6, NuGet installe l’assembly dans le net45 dossier, car il s’agit de la version la plus élevée disponible inférieure ou égale à 4.6.

Si le projet cible .NET Framework 4.6.1, par contre, NuGet installe l’assembly dans le net461 dossier.

Si le projet cible .NET Framework 4.0 et versions antérieures, NuGet lève un message d’erreur approprié pour ne pas trouver l’assembly compatible.

Regroupement d’assemblys par version du framework

NuGet copie des assemblies à partir d’un seul répertoire de bibliothèque dans le package. Par exemple, supposons qu’un package possède la structure de dossiers suivante :

\lib
    \net40
        \MyAssembly.dll (v1.0)
        \MyAssembly.Core.dll (v1.0)
    \net45
        \MyAssembly.dll (v2.0)

Lorsque le package est installé dans un projet qui cible .NET Framework 4.5, MyAssembly.dll (v2.0) est le seul assembly installé. MyAssembly.Core.dll (v1.0) n’est pas installé, car il n’est pas répertorié dans le net45 dossier. NuGet se comporte de cette façon, car MyAssembly.Core.dll pourrait avoir été fusionné dans la version 2.0 de MyAssembly.dll.

Si vous souhaitez que MyAssembly.Core.dll soit installé pour .NET Framework 4.5, placez une copie dans le dossier net45.

Regroupement d’assemblys par profil d’infrastructure

NuGet prend également en charge le ciblage d’un profil d’infrastructure spécifique en ajoutant un tiret et le nom du profil à la fin du dossier.

lib{framework name}-{profile}

Les profils pris en charge sont les suivants :

  • client: Profil client
  • full: Profil complet
  • wp:Windows Phone
  • cf: Compact Framework

Déclaration de dépendances (Avancé)

Lors de l’empaquetage d’un fichier projet, NuGet tente de générer automatiquement les dépendances à partir du projet. Les informations contenues dans cette section sur l’utilisation d’un fichier .nuspec pour déclarer des dépendances sont généralement nécessaires pour les scénarios avancés uniquement.

(Version 2.0+) Vous pouvez déclarer des dépendances de package dans le .nuspec correspondant à l’infrastructure cible du projet cible à l’aide <group> d’éléments dans l’élément <dependencies> . Pour plus d’informations, consultez l’élément dépendances.

Chaque groupe a un attribut nommé targetFramework et contient zéro ou plusieurs <dependency> éléments. Ces dépendances sont installées ensemble lorsque l’infrastructure cible est compatible avec le profil d’infrastructure du projet. Consultez les frameworks cibles pour connaître les identificateurs exacts du framework.

Nous vous recommandons d’utiliser un groupe par moniker de framework cible (TFM) pour les fichiers dans les dossiers lib/ et ref/ .

L’exemple suivant montre différentes variantes de l’élément <group> :

<dependencies>

    <group targetFramework="net472">
        <dependency id="jQuery" version="1.10.2" />
        <dependency id="WebActivatorEx" version="2.2.0" />
    </group>

    <group targetFramework="net20">
    </group>

</dependencies>

Détermination de la cible NuGet à utiliser

Lors de l’empaquetage des bibliothèques ciblant la bibliothèque de classes portables, il peut être difficile de déterminer la cible NuGet que vous devez utiliser dans vos noms de dossiers et .nuspec fichiers, en particulier si vous ciblez uniquement un sous-ensemble de la bibliothèque de classes portables. Les ressources externes suivantes vous aideront à procéder comme suit :

Fichiers de contenu et scripts PowerShell

Avertissement

Les fichiers de contenu mutables et l’exécution de script sont disponibles uniquement avec le packages.config format ; ils sont déconseillés avec tous les autres formats et ne doivent pas être utilisés pour les nouveaux packages.

Avec packages.config, les fichiers de contenu et les scripts PowerShell peuvent être regroupés par framework cible à l’aide de la même convention de répertoire à l’intérieur des dossiers content et tools. Par exemple:

\content
    \net46
        \MyContent.txt
    \net461
        \MyContent461.txt
    \uap
        \MyUWPContent.html
    \netcore
\tools
    init.ps1
    \net46
        install.ps1
        uninstall.ps1
    \uap
        install.ps1
        uninstall.ps1

Si un dossier d’infrastructure est laissé vide, NuGet n’ajoute pas de références d’assembly ou de fichiers de contenu ou exécute les scripts PowerShell pour cette infrastructure.

Note

Étant donné qu'elle init.ps1 est exécutée au niveau de la solution et n'est pas dépendante du projet, elle doit être placée directement sous le dossier tools. Elle est ignorée si elle est placée sous un dossier framework.