Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Assemblies används på två olika sätt under en build-process. Den första är för kompilering, vilket gör att paketkonsumentens kod kan kompileras mot API:er i sammansättningen och att Intellisense ger förslag. Den andra är runtime, där sammansättningen kopieras till bin katalogen och används under programkörningen. Vissa paketförfattare vill bara ha sina egna sammansättningar (eller en delmängd av sina sammansättningar) tillgängliga för sina paketkonsumenter vid kompileringstiden, men måste ange alla sina beroenden för körning. I det här dokumentet går vi tillväga för att uppnå det här resultatet.
Rekommenderas: En sammansättning per paket
Vår rekommendation är att ha ett paket per sammansättning och paketberoenden till andra sammansättningar. När NuGet återställer ett projekt genomför det val av tillgångar och stöder att inkludera, exkludera och göra olika tillgångsklasser privata. För att förhindra att ditt pakets beroenden blir kompilerade tidstillgångar för alla som använder paketet kan du göra compile tillgångar privata. I det genererade paketet kommer det att leda compile till att det undantas från beroendet. Observera att standardtillgångarna för privata tillgångar, när ingen specificeras, är contentfiles;build;analyzers. Därför bör du använda PrivateAssets="compile;contentfiles;build;analyzers" i din PackageReference eller 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>
Om du skapar ett paket från en anpassad nuspec fil i stället för att låta NuGet generera ett automatiskt åt dig bör du nuspec använda exclude XML-attributet .
<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>
Det finns tre orsaker till varför detta är den rekommenderade lösningen.
För det första refereras ofta användbara sammansättningar av nya sammansättningar/paket. En verktygssammansättning kan vara avsedd att endast användas av ett enda paket i dag, vilket gör det frestande att skicka båda sammansättningarna i ett enda paket, men om ett andra paket vill använda den "privata" verktygssammansättningen i framtiden, måste antingen verktygssammansättningen flyttas till ett nytt paket och det gamla paketet måste uppdateras för att deklarera det som ett beroende, eller verktygspaketet måste skickas i både det befintliga och det nya paketet. Om sammansättningen levereras i två olika paket och ett projekt refererar till båda paketen, om det finns olika versioner av verktygssammansättningen i de två paketen, kan NuGet inte hjälpa till med versionshantering.
För det andra kan det finnas tillfällen då utvecklarna som använder ditt paket också vill använda API:er från dina beroenden. Tänk till exempel på paketet Microsoft.ServiceHub.Client version 3.0.3078. Om du laddar ned paketet och kontrollerar nuspec filen kan du se att det visar två paket som börjar med Microsoft.VisualStudio. som beroenden, vilket innebär att det behöver dem vid körning, men det utesluter även deras kompileringstillgångar. Det innebär att projekt som använder Microsoft.ServiceHub.Client inte har Visual Studio-API:erna tillgängliga i IntelliSense eller om de skapar projektet, såvida inte projektet uttryckligen installerar dessa paket. Det här är fördelen som ett paketberoende med en utesluten resurs har. Projekt som använder ditt paket, om de också vill använda dina beroenden, kan de lägga till en referens till paketet för att göra API:erna tillgängliga för sig själva.
Slutligen har vissa paketförfattare tidigare varit förvirrade över NuGets sammansättningsval för paket som stöder mer än ett målramverk när deras paket också innehåller flera sammansättningar. Om huvudsammansättningen stöder andra målramverk än verktygssammansättningen, kanske det inte är uppenbart i vilka kataloger alla sammansättningar ska placeras. Genom att separera varje paket med sammansättningsnamn är det mer intuitivt vilka mappar varje lib/ sammansättning ska gå in på. Observera att detta inte innebär att ha Package1.net48 och Package1.net6.0 paket. Det innebär att ha lib/net48/Package1.dll och lib/net6.0/Package6.0 i Package1, och lib/netstandard2.0/Package2.dlllib/net5.0/Package2.dll i Package2. När Nuget återställer ett projekt gör Nuget oberoende tillgångsval för de två paketen.
Observera också att beroenden att inkludera/exkludera resurser endast används av projekt som använder PackageReference. Alla projekt som installerar ditt paket med packages.config kommer att installera dess beroenden och ha deras API:er tillgängliga.
packages.config stöds endast av Visual Studios äldre .NET Framework-projektmallar. SDK-stilprojekt, även de som riktar sig mot .NET Framework, stöder inte packages.config, och stöder därför att inkludera/exkludera beroende tillgångar.
Rekommenderas inte: Flera sammansättningar i ett paket
PackageReference och packages.config har olika funktioner tillgängliga. Oavsett om du vill stödja dina paketkonsumenter som använder PackageReference, packages.config eller båda, det påverkar hur du behöver skapa ditt paket.
NuGets MSBuild Pack-target stöder inte automatisk inkludering av projektreferenser i paketet. De refererade projekten listas bara som paketberoenden. Det finns ett problem på GitHub, där communitymedlemmar delade hur de uppnådde det här resultatet, vilket vanligtvis innebär att använda PackagePath MSBuild-objektmetadata för att placera filer var som helst i paketet, enligt beskrivningen i dokumenten om att inkludera innehåll i ett paket, och använda SuppressDependenciesWhenPacking för att undvika att projektreferenserna blir paketberoenden. Det finns också community-utvecklade verktyg som kan användas som ett alternativ till NuGets officiella paket, som stöder den här funktionen.
PackageReference stöd
När en paketkonsument använder PackageReferenceväljer NuGet kompilerings- och körningstillgångar oberoende av varandra, enligt beskrivningen ovan.
Kompilera tillgångar föredrar ref/<tfm>/*.dll (till exempel ref/net6.0/*.dll), men om det inte finns kommer det att återgå till lib/<tfm>/*.dll (till exempel lib/net6.0/*.dll).
Runtime-tillgångar föredrar runtimes/<rid>/lib/<tfm>/*.dll (till exempel (runtimes/win11-x64/lib/net6.0/*.dll)), men om det inte finns kommer det att återgå till lib/<tfm>/*.dll.
Eftersom sammansättningar i ref\<tfm>\ inte används vid körning kan de vara metadatasammansättningar för att minska paketstorleken.
packages.config stöd
Projekt som använder packages.config för att hantera NuGet-paket lägger normalt till referenser till alla sammansättningar i lib\<tfm>\ katalogen. Katalogen ref\ lades till för att stödja PackageReference och därmed inte beaktas när packages.config används. Om du uttryckligen vill ange vilka assemblys som ska refereras för projekt som använder packages.config, måste paketet använda <references>-elementet i nuspec-filen. Till exempel:
<references>
<group targetFramework="net45">
<reference file="MyLibrary.dll" />
</group>
</references>
MSBuild-paketmålen stöder inte elementet <references> . Se dokumenten om att packa med hjälp av en .nuspec-fil när du använder MSBuild-paketet.
Anmärkning
packages.config projektet använder en process med namnet ResolveAssemblyReference för att kopiera sammansättningar till utdatakatalogen bin\<configuration>\ . Projektets sammansättning kopieras, sedan tittar byggsystemet på sammansättningsmanifestet för refererade sammansättningar, kopierar sedan dessa sammansättningar och upprepas rekursivt för alla sammansättningar. Det innebär att om någon av sammansättningarna endast läses in av reflektion (Assembly.LoadMEF eller något annat beroendeinmatningsramverk) kanske det inte kopieras till projektets bin\<configuration>\ utdatakatalog trots att det finns i bin\<tfm>\. Det innebär också att detta endast fungerar för .NET-sammansättningar, inte för intern kod som anropas med P/Invoke.
Stöd för både PackageReference och packages.config
Viktigt!
Om ett paket innehåller nuspec-elementet <references> och inte innehåller sammansättningar i ref\<tfm>\annonserar NuGet de sammansättningar som anges i nuspec-elementet <references> som både kompilerings- och körningstillgångar. Det innebär att det kommer att bli körningsundantag när de refererade assemblys behöver ladda andra assemblys i lib\<tfm>\ katalogen. Därför är det viktigt att använda både nuspecen <references> som packages.config stöd, samt kopiera assemblies i ref/ mapp för PackageReference stöd. Paketmappen runtimes/ behöver inte användas, den lades till i avsnittet ovan för att slutföra informationen.
Example
Mitt paket innehåller tre sammansättningar, MyLib.dll, MyHelpers.dll och MyUtilities.dll, som är inriktade på .NET Framework 4.7.2.
MyUtilities.dll innehåller klasser som endast är avsedda att användas av de andra två sammansättningarna, så jag vill inte göra dessa klasser tillgängliga i IntelliSense eller vid kompileringstid för projekt som använder mitt paket. Min nuspec fil måste innehålla följande XML-element:
<references>
<group targetFramework="net472">
<reference file="MyLib.dll" />
<reference file="MyHelpers.dll" />
</group>
</references>
Jag måste se till att paketinnehållet är:
lib\net472\MyLib.dll
lib\net472\MyHelpers.dll
lib\net472\MyUtilities.dll
ref\net472\MyLib.dll
ref\net472\MyHelpers.dll