Prendre en charge plusieurs versions de .NETSupport multiple .NET versions

De nombreuses bibliothèques ciblent une version spécifique de .NET Framework.Many libraries target a specific version of the .NET Framework. Par exemple, vous pouvez avoir une première version de votre bibliothèque propre à la plateforme Windows universelle (UWP) et une autre version qui exploite les fonctionnalités de .NET Framework 4.6.For example, you might have one version of your library that's specific to UWP, and another version that takes advantage of features in .NET Framework 4.6. Pour ce faire, NuGet prend en charge le placement de plusieurs versions de la même bibliothèque dans un package unique.To accommodate this, NuGet supports putting multiple versions of the same library in a single package.

Cet article décrit la disposition d’un package NuGet, quelle que soit la façon dont le package ou les assemblys sont créés (ce qui signifie que la disposition est la même, que vous utilisiez plusieurs fichiers .csproj non-SDK-style et un fichier .nuspec personnalisé, ou un fichier .csproj multicible unique SDK-style).This article describes the layout of a NuGet package, regardless of how the package or assemblies are built (that is, the layout is the same whether using multiple non-SDK-style .csproj files and a custom .nuspec file, or a single multi-targetecd SDK-style .csproj). Pour un projet SDK-style, les cibles de packs NuGet savent comment le package doit être disposé, automatisent le placement des assemblys dans les dossiers de bibliothèque corrects et créent des groupes de dépendances pour chaque framework cible (TFM).For an SDK-style project, NuGet pack targets knows how the package must be layed out and automates putting the assemblies in the correct lib folders and creating dependency groups for each target framework (TFM). Pour des instructions détaillées, consultez Prendre en charge plusieurs versions de .NET Framework dans votre fichier projet.For detailed instructions, see Support multiple .NET Framework versions in your project file.

Vous devez disposer manuellement le package comme décrit dans cet article lorsque vous utilisez la méthode de répertoire de travail basée sur une convention décrite dans Création d’un package.You must manually lay out the package as described in this article when using the convention-based working directory method described in Creating a package. Pour un projet SDK-style, la méthode automatisée est recommandée, mais vous pouvez également choisir de disposer manuellement le package comme décrit dans cet article.For an SDK-style project, the automated method is recommended, but you may also choose to manually lay out the package as described in this article.

Structure de dossiers de la version du frameworkFramework version folder structure

Lorsque vous créez un package qui contient uniquement une version d’une bibliothèque ou qui cible plusieurs frameworks, vous créez systématiquement des sous-dossiers dans le dossier lib en utilisant des noms de framework différents qui respectent la casse selon la convention suivante :When building a package that contains only one version of a library or target multiple frameworks, you always make subfolders under lib using different case-sensitive framework names with the following convention:

lib\{framework name}[{version}]

Pour obtenir la liste complète des noms pris en charge, consultez les informations de référence sur les versions cibles de .Net Framework.For a complete list of supported names, see the Target Frameworks reference.

Vous ne devez jamais avoir une version de la bibliothèque qui n’est pas propre à un framework et placée directement dans le dossier lib racine.You should never have a version of the library that is not specific to a framework and placed directly in the root lib folder. (Cette fonctionnalité était prise en charge uniquement avec packages.config).(This capability was supported only with packages.config). En effet, la bibliothèque serait alors compatible avec n’importe quelle version cible de .Net Framework et pourrait être installée n’importe où, entraînant des erreurs inattendues du runtime.Doing so would make the library compatible with any target framework and allow it to be installed anywhere, likely resulting in unexpected runtime errors. L’ajout d’assemblys dans le dossier racine (comme lib\abc.dll) ou des sous-dossiers (comme lib\abc\abc.dll) est déprécié et ignoré lorsque vous utilisez le format PackagesReference.Adding assemblies in the root folder (such as lib\abc.dll) or subfolders (such as lib\abc\abc.dll) has been deprecated and is ignored when using the PackagesReference format.

Par exemple, la structure de dossiers suivante prend en charge quatre versions d’un assembly propres à un framework :For example, the following folder structure supports four versions of an assembly that are framework-specific:

\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 section <files> de votre .nuspec :To easily include all these files when building the package, use a recursive ** wildcard in the <files> section of your .nuspec:

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

Dossiers propres à l’architectureArchitecture-specific folders

Si vous avez des assemblys propres à une architecture, autrement dit, des assemblys distincts qui ciblent ARM, x86 et x64, vous devez les placer dans un dossier nommé runtimes au sein de sous-dossiers nommés {platform}-{architecture}\lib\{framework} ou {platform}-{architecture}\native.If you have architecture-specific assemblies, that is, separate assemblies that target ARM, x86, and x64, you must place them in a folder named runtimes within sub-folders named {platform}-{architecture}\lib\{framework} or {platform}-{architecture}\native. Par exemple, la structure de dossiers suivante s’adapte à la fois aux DLL natives et managées ciblant Windows 10 et le framework uap10.0 :For example, the following folder structure would accommodate both native and managed DLLs targeting Windows 10 and the uap10.0 framework:

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

Ces assemblys sont disponibles uniquement au moment de l’exécution. Si vous souhaitez fournir l’assembly correspondant au moment de la compilation, indiquez l’assembly AnyCPU dans le dossier /ref{tfm}.These assemblies will only be available at runtime, so if you want to provide the corresponding compile time assembly as well then have AnyCPU assembly in /ref{tfm} folder.

Notez que NuGet choisit toujours ces ressources de compilation ou d’exécution dans un seul dossier. Si des ressources compatibles se trouvent dans /ref, /lib est donc ignoré lors de l’ajout d’assemblys au moment de la compilation.Please note, NuGet always picks these compile or runtime assets from one folder so if there are some compatible assets from /ref then /lib will be ignored to add compile-time assemblies. De même, si des ressources compatibles se trouvent dans /runtime, /lib est ignoré pour l’exécution.Similarly, if there are some compatbile assets from /runtime then also /lib will be ignored for runtime.

Consultez Créer des packages UWP pour obtenir un exemple de référencement de ces fichiers dans le manifeste .nuspec.See Create UWP Packages for an example of referencing these files in the .nuspec manifest.

Consultez également Empaquetage d’un composant d’application Windows Store avec NuGet.Also, see Packing a Windows store app component with NuGet

Correspondance entre les versions d’assembly et la version cible de .Net Framework dans un projetMatching assembly versions and the target framework in a project

Lorsque NuGet installe un package qui a plusieurs versions d’assembly, il essaie de faire correspondre le nom du framework de l’assembly à la version cible de .Net Framework du projet.When NuGet installs a package that has multiple assembly versions, it tries to match the framework name of the assembly with the target framework of the project.

Si aucune correspondance n’est trouvée, NuGet copie l’assembly de la version la plus élevée inférieure ou égale à la version cible de .Net Framework du projet, si elle est disponible.If a match is not found, NuGet copies the assembly for the highest version that is less than or equal to the project's target framework, if available. Si aucun assembly compatible n’est trouvé, NuGet renvoie un message d’erreur approprié.If no compatible assembly is found, NuGet returns an appropriate error message.

Par exemple, considérez la structure de dossiers suivante dans un package :For example, consider the following folder structure in a package:

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

Quand vous installez ce package dans un projet qui cible .NET Framework 4.6, NuGet installe l’assembly dans le dossier net45, car il s’agit de la version disponible la plus élevée inférieure ou égale à 4.6.When installing this package in a project that targets .NET Framework 4.6, NuGet installs the assembly in the net45 folder, because that's the highest available version that's less than or equal to 4.6.

D’autre part, si le projet cible .NET Framework 4.6.1, NuGet installe l’assembly dans le dossier net461.If the project targets .NET Framework 4.6.1, on the other hand, NuGet installs the assembly in the net461 folder.

Si le projet cible .NET framework 4.0 et des versions antérieures, NuGet envoie un message d’erreur approprié indiquant que l’assembly compatible est introuvable.If the project targets .NET framework 4.0 and earlier, NuGet throws an appropriate error message for not finding the compatible assembly.

Regroupement d’assemblys par version du frameworkGrouping assemblies by framework version

NuGet copie des assemblys à partir d’un seul dossier de bibliothèque dans le package.NuGet copies assemblies from only a single library folder in the package. Par exemple, supposons qu’un package présente la structure de dossiers suivante :For example, suppose a package has the following folder structure:

\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é.When the package is installed in a project that targets .NET Framework 4.5, MyAssembly.dll (v2.0) is the only assembly installed. MyAssembly.Core.dll (v1.0) n’est pas installé, car il n’est pas répertorié dans le dossier net45.MyAssembly.Core.dll (v1.0) is not installed because it's not listed in the net45 folder. NuGet se comporte ainsi car MyAssembly.Core.dll a peut-être été fusionné dans la version 2.0 de MyAssembly.dll.NuGet behaves this way because MyAssembly.Core.dll might have merged into version 2.0 of MyAssembly.dll.

Si vous voulez que MyAssembly.Core.dll soit installé pour .NET Framework 4.5, placez une copie dans le dossier net45.If you want MyAssembly.Core.dll to be installed for .NET Framework 4.5, place a copy in the net45 folder.

Regroupement d’assemblys par profil du frameworkGrouping assemblies by framework profile

NuGet prend également en charge le ciblage d’un profil de framework spécifique en ajoutant un tiret et le nom du profil à la fin du dossier.NuGet also supports targeting a specific framework profile by appending a dash and the profile name to the end of the folder.

lib\{framework name}-{profile}

Les profils pris en charge sont les suivants :The supported profiles are as follows:

  • client: Profil clientclient: Client Profile
  • full: Profil completfull: Full Profile
  • wp: Windows Phonewp: Windows Phone
  • cf: Compact Frameworkcf: Compact Framework

Déclaration de dépendances (avancée)Declaring dependencies (Advanced)

Lors de la compression d’un fichier projet, NuGet tente de générer automatiquement les dépendances à partir du projet.When packing a project file, NuGet tries to automatically generate the dependencies from the project. Les informations de cette section sur l’utilisation d’un fichier .nuspec pour déclarer des dépendances sont généralement nécessaires pour des scénarios avancés uniquement.The information in this section about using a .nuspec file to declare dependencies is typically necessary for advanced scenarios only.

(Version 2.0 +) Vous pouvez déclarer des dépendances de package dans le fichier .nuspec correspondant au à la version cible de .Net Framework à l’aide d’éléments <group> au sein de l’élément <dependencies>.(Version 2.0+) You can declare package dependencies in the .nuspec corresponding to the target framework of the target project using <group> elements within the <dependencies> element. Pour plus d'informations, consultez Éléments de dépendances.For more information, see dependencies element.

Chaque groupe possède un attribut nommé targetFramework et contient zéro ou plusieurs éléments <dependency>.Each group has an attribute named targetFramework and contains zero or more <dependency> elements. Ces dépendances sont installées ensemble quand la version cible de .Net Framework est compatible avec le profil de framework du projet.Those dependencies are installed together when the target framework is compatible with the project's framework profile. Consultez Versions cibles de .NET Framework pour connaître les identificateurs de framework exacts.See Target frameworks for the exact framework identifiers.

Nous vous recommandons d’utiliser un groupe par moniker de framework cible (TFM) pour les fichiers dans les dossiers lib/ et ref/ .We recommend using one group per Target Framework Moniker (TFM) for files in the lib/ and ref/ folders.

L’exemple suivant illustre différentes variantes de l’élément <group> :The following example shows different variations of the <group> element:

<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 à utiliserDetermining which NuGet target to use

Lorsque vous empaquetez des bibliothèques ciblant la bibliothèque de classes portable, il peut être difficile de déterminer quelle cible NuGet vous devez utiliser dans vos noms de dossier et votre fichier .nuspec, en particulier si vous ciblez uniquement un sous-ensemble de la bibliothèque de classes portable.When packaging libraries targeting the Portable Class Library it can be tricky to determine which NuGet target you should use in your folder names and .nuspec file, especially if targeting only a subset of the PCL. Les ressources externes suivantes peuvent vous aider à la déterminer :The following external resources will help you with this:

Fichiers de contenu et scripts PowerShellContent files and PowerShell scripts

Avertissement

Des fichiers de contenu mutables et une exécution des scripts sont disponibles au format packages.config uniquement ; ils sont dépréciés avec tous les autres des formats et ne doivent pas être utilisés pour de nouveaux packages.Mutable content files and script execution are available with the packages.config format only; they are deprecated with all other formats and should not be used for any new packages.

Avec packages.config, il est possible de regrouper les fichiers de contenu et les scripts PowerShell par version cible de .Net Framework en utilisant la même convention de dossier à l’intérieur des dossiers content et tools.With packages.config, content files and PowerShell scripts can be grouped by target framework using the same folder convention inside the content and tools folders. Par exemple :For example:

\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 de framework est vide, NuGet n’y ajoute pas de références d’assembly ni de fichiers de contenu ou n’exécute pas les scripts PowerShell pour ce framework.If a framework folder is left empty, NuGet doesn't add assembly references or content files or run the PowerShell scripts for that framework.

Notes

Étant donné que init.ps1 s’exécute au niveau de la solution et ne dépend pas du projet, il doit être placé directement sous le dossier tools.Because init.ps1 is executed at the solution level and not dependent on project, it must be placed directly under the tools folder. Ce fichier est ignoré s’il est placé sous un dossier de framework.It's ignored if placed under a framework folder.