Notes
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 assemblages sont utilisés de deux façons différentes lors d'une compilation. La première consiste à compiler, ce qui permet à l'utilisateur du paquet de compiler contre des API dans l'assembly et à IntelliSense de donner des suggestions. Le second est runtime, où l’assembly est copié dans le bin répertoire et est utilisé pendant l’exécution du programme. Certains auteurs de paquet aimeraient que seuls leurs propres assemblies (ou un sous-ensemble de leurs assemblies) soient disponibles pour leurs consommateurs de paquet durant la compilation, mais doivent fournir toutes leurs dépendances pour l’exécution. Ce document examine les façons d’atteindre ce résultat.
Recommandé : un assemblage par paquet
Nous recommandons d'avoir un package par assembly et d'établir des dépendances de package vers d'autres assemblies. Lorsque NuGet restaure un projet, il effectue une sélection de ressources et prend en charge l’inclusion, l’exclusion et la création de classes de ressources privées différentes. Pour empêcher les dépendances de votre package de devenir des ressources de temps de compilation pour toute personne utilisant votre package, vous pouvez rendre compile les ressources privées. Dans le package généré, cela provoquera l'exclusion de compile de la dépendance. Notez que les ressources privées par défaut lorsqu’aucune ressource n’est fournie est contentfiles;build;analyzers. Par conséquent, vous devez utiliser PrivateAssets="compile;contentfiles;build;analyzers" dans votre PackageReference ou ProjectReference.
<ItemGroup>
<ProjectReference Include="..\OtherProject\OtherProject.csproj" PrivateAssets="compile;contentfiles;build;analyzers" />
<PackageReference Include="SomePackage" Version="1.2.3" PrivateAssets="compile;contentfiles;build;analyzers" />
</ItemGroup>
Si vous créez un package à partir d’un fichier personnalisé nuspec , plutôt que de laisser NuGet générer automatiquement un package pour vous, vous nuspec devez utiliser l’attribut exclude XML .
<dependencies>
<group targetFramework=".NETFramework4.8">
<dependency id="OtherProject" version="3.2.1" exclude="Compile,Build,Analyzers" />
<dependency id="SomePackage" version="1.2.3" exclude="Compile,Build,Analyzers" />
</group>
</dependencies>
Il existe trois raisons pour lesquelles il s’agit de la solution recommandée.
Tout d’abord, les assemblys utiles sont souvent référencés par de nouveaux assemblys/packages. Bien qu’un assembly utilitaire ne soit destiné qu’à être utilisé par un seul package aujourd’hui, ce qui permet d’expédier les deux assemblys dans un package unique, si un deuxième package souhaite utiliser l’assembly d’utilitaire « privé » à l’avenir, soit l’assembly de l’utilitaire doit être déplacé vers un nouveau package et l’ancien package doit être mis à jour pour le déclarer comme dépendance, ou le package utilitaire doit être expédié à la fois dans le package existant et dans le nouveau package. Si l’assembly est fourni dans deux packages différents et qu’un projet référence les deux packages, s’il existe différentes versions de l’assembly utilitaire dans les deux packages, NuGet ne peut pas aider à gérer les versions.
Deuxièmement, il peut arriver que les développeurs utilisant votre package souhaitent également utiliser des API de vos dépendances. Par exemple, considérez le package Microsoft.ServiceHub.Client version 3.0.3078. Si vous téléchargez le package et vérifiez le nuspec fichier, vous pouvez voir qu’il répertorie deux packages commençant Microsoft.VisualStudio. par des dépendances, ce qui signifie qu’il en a besoin au moment de l’exécution, mais qu’il exclut également leurs ressources de compilation. Cela signifie que les projets utilisant Microsoft.ServiceHub.Client n’ont pas les API Visual Studio disponibles dans IntelliSense ou si elles créent le projet, sauf si le projet installe explicitement ces packages. Et c'est l'avantage qu'offre une dépendance de package avec un élément d'exclusion. Les projets utilisant votre package, s’ils souhaitent également utiliser vos dépendances, ils peuvent également ajouter une référence au package pour rendre les API disponibles pour eux-mêmes.
Enfin, certains auteurs de packages ont été confus par le passé sur la sélection d’assemblages NuGet pour les packages prenant en charge plusieurs cadres cibles lorsque leur package contient également plusieurs assemblages. Si votre assembly principal prend en charge différents frameworks cibles pour votre assembly utilitaire, il peut ne pas être évident dans quels lib/ répertoires placer tous les assemblys. En séparant chaque paquet par nom d’assemblage, il devient plus intuitif de déterminer dans quels dossiers chaque assemblage doit entrer. Notez que cela ne signifie pas avoir Package1.net48 et Package1.net6.0 packages. Cela signifie avoir lib/net48/Package1.dll et lib/net6.0/Package6.0 dans Package1, et lib/netstandard2.0/Package2.dlllib/net5.0/Package2.dll en Package2. Lorsque Nuget restaure un projet, Nuget effectue indépendamment la sélection des ressources pour les deux packages.
Notez également que les éléments d'inclusion/exclusion de dépendance ne sont utilisés que par les projets qui utilisent PackageReference. Tout projet qui installe votre package à l'aide de packages.config installera vos dépendances et rendra également ses API disponibles.
packages.config est uniquement pris en charge par les anciens modèles de projet .NET Framework de Visual Studio. Les projets de style SDK, même ceux ciblant .NET Framework, ne prennent pas en charge packages.config, et par conséquent, prennent en charge les ressources d’inclusion/exclusion des dépendances.
Non recommandé : Plusieurs assemblées dans un paquet
PackageReference et packages.config disposent de différentes fonctionnalités. Que vous souhaitiez prendre en charge les consommateurs de votre package qui utilisent PackageReference, packages.config ou les deux, modifie la façon dont vous devez concevoir votre package.
La cible MSBuild Pack de NuGet ne prend pas en charge automatiquement l’inclusion de références de projet dans le package. Elle répertorie uniquement ces projets référencés en tant que dépendances de package. Il existe un problème sur GitHub, où les membres de la communauté ont partagé les moyens dont ils ont obtenu ce résultat, ce qui implique généralement l’utilisation PackagePath des métadonnées d’élément MSBuild pour placer des fichiers n’importe où dans le package, comme décrit dans la documentation sur l’inclusion de contenu dans un package et l’utilisationSuppressDependenciesWhenPacking pour éviter que les références de projet deviennent des dépendances de package. Il existe également des outils développés par la communauté qui peuvent être utilisés comme alternative au pack officiel de NuGet, qui prennent en charge cette fonctionnalité.
PackageReference soutien
Lorsqu’un consommateur de package utilise PackageReference, NuGet sélectionne les ressources de compilation et d’exécution indépendamment, comme décrit précédemment.
Les ressources de compilation préfèrent ref/<tfm>/*.dll (par exemple ref/net6.0/*.dll), mais si cela n’existe pas, elle revient à lib/<tfm>/*.dll (par exemple lib/net6.0/*.dll).
Les ressources runtime préfèrent runtimes/<rid>/lib/<tfm>/*.dll (par exemple (runtimes/win11-x64/lib/net6.0/*.dll)), mais si cela n’existe pas, elle revient à lib/<tfm>/*.dll.
Étant donné que les assemblages dans ref\<tfm>\ ne sont pas utilisés au moment de l’exécution, ils peuvent être des assemblages uniquement de métadonnées pour réduire la taille du paquet.
packages.config soutien
Les projets utilisant packages.config pour gérer les packages NuGet ajoutent normalement des références à tous les assemblys du lib\<tfm>\ répertoire. Le répertoire ref\ a été ajouté pour prendre en charge PackageReference, et n'est donc pas pris en compte lors de l'utilisation de packages.config. Pour définir explicitement quels assemblys sont référencés pour les projets utilisant
<references>
<group targetFramework="net45">
<reference file="MyLibrary.dll" />
</group>
</references>
Les cibles du pack MSBuild ne prennent pas en charge l’élément <references> . Consultez la documentation sur l’empaquetage à l’aide d’un fichier .nuspec lors de l’utilisation du pack MSBuild.
Note
packages.config le projet utilise un processus appelé ResolveAssemblyReference pour copier des assemblys dans le bin\<configuration>\ répertoire de sortie. L’assembly de votre projet est copié, puis le système de build examine le manifeste d’assembly pour les assemblys référencés, puis copie ces assemblys et se répète de manière récursive pour tous les assemblys. Cela signifie que si l'un des assemblies est chargé uniquement par réflexion (Assembly.Load, MEF ou une autre infrastructure d'injection de dépendances), il se peut qu'il ne soit pas copié dans le répertoire de sortie de votre projet bin\<configuration>\, bien qu'il soit dans bin\<tfm>\. Cela signifie également que cela fonctionne uniquement pour les assemblys .NET, et non pour le code natif appelé avec P/Invoke.
Prise en charge à la fois PackageReference et packages.config
Important
Si un package contient l’élément nuspec <references> et ne contient pas d’assemblys dans ref\<tfm>\, NuGet promeut les assemblys répertoriés dans l’élément nuspec <references> comme actifs de compilation et d’exécution. Cela signifie qu’il y aura des exceptions d’exécution lorsque les assemblys référencés doivent charger n’importe quel autre assembly dans le lib\<tfm>\ répertoire. Par conséquent, il est important d'utiliser à la fois le fichier nuspec <references> pour la prise en charge de packages.config, ainsi que de dupliquer des assemblies dans le dossier ref/ pour la prise en charge de PackageReference. Le dossier de package runtimes/ n’a pas besoin d’être utilisé, il a été ajouté à la section ci-dessus pour des raisons d’exhaustivité.
Example
Mon package contient trois assemblys, MyLib.dllMyHelpers.dll et MyUtilities.dll, qui ciblent .NET Framework 4.7.2.
MyUtilities.dll contient des classes destinées à être utilisées uniquement par les deux autres assemblys. Par conséquent, je ne veux pas rendre ces classes disponibles dans IntelliSense ou au moment de la compilation pour les projets utilisant mon package. Mon nuspec fichier doit contenir les éléments XML suivants :
<references>
<group targetFramework="net472">
<reference file="MyLib.dll" />
<reference file="MyHelpers.dll" />
</group>
</references>
J’ai besoin de vérifier que mon contenu de package est le suivant :
lib\net472\MyLib.dll
lib\net472\MyHelpers.dll
lib\net472\MyUtilities.dll
ref\net472\MyLib.dll
ref\net472\MyHelpers.dll