Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Assemblies worden op twee verschillende manieren gebruikt tijdens een buildproces. De eerste is voor compileren, waardoor de code van de pakketgebruiker kan worden gecompileerd op basis van API's in de assembly en dat IntelliSense suggesties kan geven. De tweede is runtime, waarbij de assembly wordt gekopieerd naar de bin map en wordt gebruikt tijdens het uitvoeren van het programma. Sommige pakketauteurs willen alleen hun eigen assembly's (of een subset van hun assembly's) die tijdens het compileren beschikbaar zijn voor hun pakketgebruikers, maar moeten alle afhankelijkheden voor runtime opgeven. In dit document wordt gekeken naar manieren om dit resultaat te bereiken.
Aanbevolen: Één assembly per pakket
Onze aanbeveling is om één pakket per assembly en pakketafhankelijkheden voor andere assembly's te hebben. Wanneer NuGet een project herstelt, voert het een assetselectie uit en ondersteunt het de inclusie, exclusie en het privé houden van verschillende assetklassen. Als u wilt voorkomen dat de afhankelijkheden van uw pakket compileertijdbronnen worden voor iedereen die uw pakket gebruikt, kunt u deze bronnen privé maken compile . In het gegenereerde pakket zal compile worden uitgesloten van de afhankelijkheid. Houd er rekening mee dat de standaard privéactiva contentfiles;build;analyzers is wanneer er geen wordt opgegeven. U moet daarom PrivateAssets="compile;contentfiles;build;analyzers" in uw PackageReference of ProjectReference gebruiken.
<ItemGroup>
<ProjectReference Include="..\OtherProject\OtherProject.csproj" PrivateAssets="compile;contentfiles;build;analyzers" />
<PackageReference Include="SomePackage" Version="1.2.3" PrivateAssets="compile;contentfiles;build;analyzers" />
</ItemGroup>
Als u een pakket maakt op basis van een aangepast nuspec bestand in plaats van nuGet automatisch een pakket voor u te laten genereren, moet u nuspec het exclude XML-kenmerk gebruiken.
<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>
Er zijn drie redenen waarom dit de aanbevolen oplossing is.
Ten eerste verwijzen nieuwe assemblies/pakketten vaak naar nuttige assemblies. Hoewel een hulpprogramma-assembly bedoeld kan zijn om alleen door één pakket te worden gebruikt, is het verleidelijk om beide assemblies in één pakket te verzenden. Als in de toekomst een tweede pakket de "private" hulpprogramma-assembly wil gebruiken, moet de hulpprogramma-assembly naar een nieuw pakket worden verplaatst en moet het oude pakket worden bijgewerkt om het als een afhankelijkheid te declareren. Alternatief kan het hulpprogrammapakket in zowel het bestaande als het nieuwe pakket worden verzonden. Als de assembly wordt geleverd in twee verschillende pakketten en een project verwijst naar beide pakketten, als er verschillende versies van de assembly van het hulpprogramma in de twee pakketten zijn, kan NuGet niet helpen bij versiebeheer.
Ten tweede kan het voorkomen dat de ontwikkelaars die uw pakket gebruiken, ook API's van uw afhankelijkheden willen gebruiken. Denk bijvoorbeeld aan het pakket Microsoft.ServiceHub.Client versie 3.0.3078. Als u het pakket downloadt en het nuspec bestand controleert, ziet u dat er twee pakketten worden vermeld die beginnen Microsoft.VisualStudio. met afhankelijkheden, wat betekent dat het ze tijdens runtime nodig heeft, maar dat het ook hun compile-assets uitsluit. Dit betekent dat voor projecten die microsoft.ServiceHub.Client gebruiken, de Visual Studio-API's niet beschikbaar zijn in IntelliSense of als ze het project bouwen, tenzij het project deze pakketten expliciet installeert. En dit is het voordeel dat een pakketafhankelijkheid met een uitgesloten asset heeft. Projecten die gebruikmaken van uw pakket, als ze ook uw afhankelijkheden willen gebruiken, kunnen ze een verwijzing naar het pakket toevoegen om de API's beschikbaar te maken voor zichzelf.
Ten slotte zijn sommige pakketauteurs in het verleden verward met de assemblyselectie van NuGet voor pakketten die meer dan één doelframework ondersteunen wanneer hun pakket ook meerdere assembly's bevat. Als uw hoofdassembly verschillende doelframeworks ondersteunt voor de assembly van uw hulpprogramma, is het mogelijk niet duidelijk in welke lib/ mappen alle assembly's moeten worden geplaatst. Door elk pakket te scheiden op assemblynaam, is het intuïtiever in welke lib/ mappen elke assembly moet worden opgenomen. Opmerking: dit betekent niet dat er Package1.net48- en Package1.net6.0-pakketten zijn. Het betekent lib/net48/Package1.dll en lib/net6.0/Package6.0 in Package1, en lib/netstandard2.0/Package2.dll en lib/net5.0/Package2.dll in Package2. Wanneer Nuget een project herstelt, voert Nuget onafhankelijk assetselectie uit voor de twee pakketten.
Houd er ook rekening mee dat het opnemen/uitsluiten van afhankelijkheidsassets alleen wordt gebruikt door projecten die PackageReference gebruiken. Elke installatie van uw pakket door een project met packages.config zal ook uw afhankelijkheden installeren en zijn API's beschikbaar maken.
packages.config wordt alleen ondersteund door de oudere .NET Framework-projectsjablonen van Visual Studio. SDK-stijlprojecten, zelfs projecten die gericht zijn op .NET Framework, ondersteunen packages.config niet, en bieden daarom ook geen ondersteuning voor afhankelijkheidsinsluiting of -uitsluiting van assets.
Niet aanbevolen: Meerdere assembly's in één pakket
PackageReference en packages.config er zijn verschillende functies beschikbaar. Of u nu uw pakketgebruikers wilt ondersteunen die PackageReferencegebruikmaken van, packages.configof beide, verandert hoe u uw pakket moet ontwerpen.
Het MSBuild Pack-doel van NuGet biedt geen ondersteuning voor het automatisch opnemen van projectverwijzingen in het pakket. Alleen de projecten waarnaar wordt verwezen, worden weergegeven als pakketafhankelijkheden. Er is een probleem op GitHub, waarbij communityleden deze uitkomst hebben gedeeld, waarbij meestal metagegevens van MSBuild-items worden gebruikt PackagePath om bestanden overal in het pakket te plaatsen, zoals beschreven in de documenten over het opnemen van inhoud in een pakket en om SuppressDependenciesWhenPacking te voorkomen dat de projectverwijzingen pakketafhankelijkheden worden. Er bestaan ook door de community ontwikkelde hulpprogramma's die kunnen worden gebruikt als alternatief voor het officiële pakket van NuGet, die deze functie ondersteunen.
ondersteuning voor PackageReference
Wanneer een pakketgebruiker gebruikmaakt PackageReference, selecteert NuGet onafhankelijk van elkaar compileer- en runtime-assets, zoals eerder beschreven.
Compileer assets bij voorkeur ref/<tfm>/*.dll (bijvoorbeeld ref/net6.0/*.dll), maar als dat niet bestaat, valt het terug op lib/<tfm>/*.dll (bijvoorbeeld lib/net6.0/*.dll).
Runtime-assets geven de voorkeur runtimes/<rid>/lib/<tfm>/*.dll (bijvoorbeeld (runtimes/win11-x64/lib/net6.0/*.dll)), maar als dat niet bestaat, valt deze terug op lib/<tfm>/*.dll.
Omdat assembly's tijdens ref\<tfm>\ runtime niet worden gebruikt, kunnen ze assembly's met alleen metagegevens zijn om de pakketgrootte te verkleinen.
ondersteuning voor packages.config
Projecten die packages.config gebruiken om NuGet-pakketten te beheren, voegen normaal gesproken verwijzingen toe aan alle assembly's in de lib\<tfm>\ map. De ref\ map is toegevoegd om PackageReference te ondersteunen en wordt daarom niet meegenomen bij het gebruik van packages.config. Als u expliciet wilt instellen naar welke assembly's worden verwezen voor projecten die worden gebruikt packages.config, moet het pakket het <references> element in het nuspec-bestand gebruiken. Voorbeeld:
<references>
<group targetFramework="net45">
<reference file="MyLibrary.dll" />
</group>
</references>
De MSBuild pack-doelen ondersteunen het <references> element niet. Zie de documenten over het verpakken met behulp van een .nuspec-bestand wanneer u MSBuild pack gebruikt.
Opmerking
packages.config project gebruikt een proces met de naam ResolveAssemblyReference om assembly's te kopiëren naar de bin\<configuration>\ uitvoermap. De assembly van uw project wordt gekopieerd en vervolgens kijkt het buildsysteem naar het assemblymanifest voor assembly's waarnaar wordt verwezen, en kopieert deze assembly's en herhaalt deze recursief voor alle assembly's. Dit betekent dat als een van de assembly's alleen wordt geladen door weerspiegeling (Assembly.LoadMEF of een ander afhankelijkheidsinjectieframework), deze mogelijk niet wordt gekopieerd naar de uitvoermap van bin\<configuration>\ uw project ondanks dat deze zich in bin\<tfm>\bevindt. Dit betekent ook dat dit alleen werkt voor .NET-assembly's, niet voor systeemeigen code die wordt aangeroepen met P/Invoke.
Ondersteunt zowel PackageReference als packages.config.
Belangrijk
Als een pakket het nuspec-element <references> bevat en geen assembly's ref\<tfm>\bevat, zal NuGet de assembly's die in het nuspec-element <references> worden vermeld, adverteren als zowel de compileer- als runtimeassets. Dit betekent dat er runtime-uitzonderingen zijn wanneer de assembly's waarnaar wordt verwezen, andere assembly's in de lib\<tfm>\ map moeten laden. Daarom is het belangrijk om zowel de nuspec <references> te gebruiken voor packages.config ondersteuning als het dupliceren van assembly's in de ref/ map voor PackageReference ondersteuning. De runtimes/ pakketmap hoeft niet te worden gebruikt, deze is toegevoegd aan de bovenstaande sectie voor volledigheid.
Example
Mijn pakket bevat drie assembly's, MyLib.dllMyHelpers.dll enMyUtilities.dll, die gericht zijn op .NET Framework 4.7.2.
MyUtilities.dll bevat klassen die alleen door de andere twee assembly's moeten worden gebruikt, dus ik wil deze klassen niet beschikbaar maken in IntelliSense of tijdens het compileren van projecten met behulp van mijn pakket. Mijn nuspec bestand moet de volgende XML-elementen bevatten:
<references>
<group targetFramework="net472">
<reference file="MyLib.dll" />
<reference file="MyHelpers.dll" />
</group>
</references>
Ik moet ervoor zorgen dat mijn pakketinhoud het volgende is:
lib\net472\MyLib.dll
lib\net472\MyHelpers.dll
lib\net472\MyUtilities.dll
ref\net472\MyLib.dll
ref\net472\MyHelpers.dll