Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Assemblies werden während einer Kompilierung auf zwei verschiedene Arten verwendet. Die erste ist für die Kompilierung vorgesehen, bei der der Code des Paketanwenders gegen die APIs in der Assembly kompiliert werden kann und Intellisense Vorschläge liefern kann. Die zweite ist Laufzeit, wobei die Assembly in das bin Verzeichnis kopiert wird und während der Programmausführung verwendet wird. Einige Paketautoren möchten, dass nur ihre eigenen Assemblys (oder eine Teilmenge ihrer Assemblys) zur Kompilierungszeit für ihre Paketanwender verfügbar sind, aber alle ihre Abhängigkeiten zur Laufzeit bereitstellen müssen. In diesem Dokument werden Möglichkeiten zum Erreichen dieses Ergebnisses untersucht.
Empfohlen: Eine Baugruppe pro Paket
Unsere Empfehlung besteht darin, ein Paket pro Assembly und Paketabhängigkeiten für andere Assemblys zu verwenden. Wenn NuGet ein Projekt wiederherstellt, erfolgt die Asset-Auswahl und es unterstützt das Einschließen, Ausschließen und Privatisieren verschiedener Asset-Klassen. Um zu verhindern, dass die Abhängigkeiten Ihres Pakets zu Kompilierungszeitressourcen für alle Benutzer Ihres Pakets werden, können Sie Ressourcen privat machen compile . Im generierten Paket wird dies zum Ausschluss von compile aus der Abhängigkeit führen. Beachten Sie, dass die privaten Standardressourcen contentfiles;build;analyzers sind, wenn keine angegeben wird. Daher sollten Sie PrivateAssets="compile;contentfiles;build;analyzers" in Ihrem PackageReference oder ProjectReference verwenden.
<ItemGroup>
<ProjectReference Include="..\OtherProject\OtherProject.csproj" PrivateAssets="compile;contentfiles;build;analyzers" />
<PackageReference Include="SomePackage" Version="1.2.3" PrivateAssets="compile;contentfiles;build;analyzers" />
</ItemGroup>
Wenn Sie ein Paket aus einer benutzerdefinierten nuspec Datei erstellen, anstatt es von NuGet automatisch generieren zu lassen, sollten Sie das exclude XML-Attribut in nuspec verwenden.
<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>
Es gibt drei Gründe, warum dies die empfohlene Lösung ist.
Zunächst werden nützliche Assemblys häufig von neuen Assemblys oder Paketen referenziert. Eine Dienstprogrammassembly mag zwar heute nur für ein einzelnes Paket vorgesehen sein, was dazu verleiten könnte, beide Assemblys in einem einzigen Paket zu versenden. Sollte jedoch ein zweites Paket in Zukunft die "private" Dienstprogrammassembly verwenden wollen, muss entweder die Dienstprogrammassembly in ein neues Paket verschoben und das alte Paket aktualisiert werden, um dieses als Abhängigkeit zu deklarieren, oder das Dienstprogrammpaket muss sowohl im bestehenden als auch im neuen Paket enthalten sein. Wenn die Assembly in zwei verschiedenen Paketen ausgeliefert wird und ein Projekt auf beide Pakete verweist, wenn in den beiden Paketen unterschiedliche Versionen der Hilfsassembly vorhanden sind, kann NuGet die Versionsverwaltung nicht unterstützen.
Zweitens kann es vorkommen, dass entwickler, die Ihr Paket verwenden, auch APIs aus Ihren Abhängigkeiten verwenden möchten. Betrachten Sie beispielsweise das Paket "Microsoft.ServiceHub.Client", Version 3.0.3078. Wenn Sie das Paket herunterladen und die nuspec Datei überprüfen, können Sie sehen, dass es zwei Pakete auflistet, die mit Microsoft.VisualStudio. abhängigkeiten beginnen, d. h. sie benötigt sie zur Laufzeit, schließt aber auch deren Kompilierungsressourcen aus. Dies bedeutet, dass Projekte, die Microsoft.ServiceHub.Client verwenden, nicht über die Visual Studio-APIs in IntelliSense verfügen oder wenn sie das Projekt erstellen, es sei denn, das Projekt installiert diese Pakete explizit. Und dies ist der Vorteil einer Paketabhängigkeit, die einen ausgeschlossenen Bestandteil umfasst. Projekte, die Ihr Paket verwenden, können sie, wenn sie auch Ihre Abhängigkeiten verwenden möchten, einen Verweis auf das Paket hinzufügen, um die APIs für sich selbst verfügbar zu machen.
Schließlich waren einige Paketautoren in der Vergangenheit verwirrt darüber, wie NuGet die Auswahl der Assemblys für Pakete trifft, die mehr als ein Zielframework unterstützen, insbesondere wenn ihr Paket auch mehrere Assemblys enthält. Wenn Ihre Hauptassembly andere Zielframeworks als die Hilfsprogrammassembly unterstützt, könnte es unklar sein, in welche lib/ Verzeichnisse alle Assemblys eingefügt werden sollen. Durch das Trennen jedes Pakets nach Assemblynamen ist es intuitiver, in welche lib/ Ordner die einzelnen Assemblys eingefügt werden sollen. Beachten Sie, dass dies nicht bedeutet, dass es Package1.net48 und Package1.net6.0 Pakete gibt. Es bedeutet, dass lib/net48/Package1.dll und lib/net6.0/Package6.0 in Package1 vorhanden sind und lib/netstandard2.0/Package2.dll sowie lib/net5.0/Package2.dll in Package2. Wenn NuGet ein Projekt wiederherstellt, führt NuGet unabhängig die Auswahl der Assets für die beiden Pakete durch.
Beachten Sie außerdem, dass Abhängigkeitsressourcen zum Ein- und Ausschließen von Projekten nur von solchen verwendet werden, die PackageReference nutzen. Jedes Projekt, das Ihr Paket mit packages.config installiert, installiert Ihre Abhängigkeiten und hat auch die APIs zur Verfügung.
packages.config wird nur von den älteren .NET Framework-Projektvorlagen von Visual Studio unterstützt. SDK-Stilprojekte, selbst wenn sie das .NET Framework anvisieren, unterstützen packages.config nicht und unterstützen daher Include-/Exclude-Abhängigkeitsassets.
Nicht empfohlen: Mehrere Assemblys in einem Paket
PackageReference und packages.config haben unterschiedliche Features zur Verfügung. Unabhängig davon, ob Sie Ihre Paketnutzer unterstützen möchten, die PackageReference, packages.config oder beides verwenden, wirkt sich dies darauf aus, wie Sie Ihr Paket erstellen müssen.
Das MSBuild Pack-Ziel von NuGet unterstützt nicht automatisch das Einschließen von Projektverweise in das Paket. Sie listet nur die Projekte auf, auf die verwiesen wird, als Paketabhängigkeiten. Es gibt ein Thema auf GitHub, bei dem Mitglieder der Community Methoden geteilt haben, wie sie dieses Ergebnis erreicht haben. Dies umfasst normalerweise die Verwendung von PackagePath MSBuild-Elementmetadaten, um Dateien an beliebigen Stellen im Paket zu platzieren, wie in den Dokumenten zum Einfügen von Inhalten in ein Paket beschrieben, sowie die Verwendung von SuppressDependenciesWhenPacking, um zu verhindern, dass Projektverweise zu Paketabhängigkeiten werden. Es gibt auch community entwickelte Tools, die als Alternative zum offiziellen Paket von NuGet verwendet werden können, das dieses Feature unterstützt.
PackageReference-Unterstützung
Wenn ein Paketanwender verwendet PackageReference, wählt NuGet wie zuvor beschrieben Kompilierungs- und Laufzeitressourcen unabhängig voneinander aus.
Kompilierungsressourcen bevorzugen ref/<tfm>/*.dll (z. B ref/net6.0/*.dll. ), aber wenn dies nicht vorhanden ist, wird sie wieder auf lib/<tfm>/*.dll (z. B lib/net6.0/*.dll. ) zurückfallen.
Laufzeitressourcen bevorzugen runtimes/<rid>/lib/<tfm>/*.dll (z. B. runtimes/win11-x64/lib/net6.0/*.dll), aber wenn diese nicht vorhanden sind, fällt sie auf lib/<tfm>/*.dll zurück.
Da Assemblys zur ref\<tfm>\ Laufzeit nicht verwendet werden, können sie nur Metadatenassemblys sein, um die Paketgröße zu verringern.
packages.config-Unterstützung
Projekte, die packages.config zum Verwalten von NuGet-Paketen verwenden, fügen normalerweise Verweise auf alle Assemblies im lib\<tfm>\ Verzeichnis hinzu. Das ref\ Verzeichnis wurde zur Unterstützung PackageReference hinzugefügt und wird daher bei der Verwendung packages.confignicht berücksichtigt. Um explizit festzulegen, welche Assemblys für Projekte verwendet werden, die packages.config nutzen, muss das Paket das <references>-Element in der Nuspec-Datei verwenden. Beispiel:
<references>
<group targetFramework="net45">
<reference file="MyLibrary.dll" />
</group>
</references>
Die MSBuild-Packziele unterstützen das <references> Element nicht. Informationen zum Packen mithilfe einer NUSPEC-Datei finden Sie in den Dokumenten zur Verpackung bei Verwendung des MSBuild-Pakets.
Hinweis
packages.config Projekt verwendet einen Prozess namens ResolveAssemblyReference , um Assemblys in das bin\<configuration>\ Ausgabeverzeichnis zu kopieren. Die Assembly Ihres Projekts wird kopiert, dann schaut sich das Buildsystem das Assembly-Manifest nach referenzierten Assemblys an, kopiert diese Assemblys und wiederholt den Vorgang rekursiv für alle referenzierten Assemblys. Dies bedeutet, dass eine der Assemblys, die nur durch Reflexion geladen wurden (Assembly.Load, MEF oder ein anderes Abhängigkeitseinfügungsframework), möglicherweise nicht in das bin\<configuration>\-Ausgabeverzeichnis Ihres Projekts kopiert wird, obwohl sie sich in bin\<tfm>\ befindet. Dies bedeutet auch, dass dies nur für .NET-Assemblys funktioniert, nicht für systemeigenen Code, der mit P/Invoke aufgerufen wird.
Unterstützen sowohl PackageReference als auch packages.config
Von Bedeutung
Wenn ein Paket das Nuspec-Element <references> enthält und keine Assemblys in ref\<tfm>\ enthält, wird NuGet die im Nuspec-Element <references> aufgeführten Assemblys als sowohl Kompilierungs- als auch Laufzeitressourcen ankündigen. Dies bedeutet, dass Laufzeit-Ausnahmen auftreten, wenn die referenzierten Assemblys alle anderen Assemblys im lib\<tfm>\ Verzeichnis laden müssen. Daher ist es wichtig, sowohl das nuspec <references> für packages.config Unterstützung zu verwenden, als auch Assemblys im ref/ Ordner für PackageReference Unterstützung zu duplizieren. Der runtimes/ Paketordner muss nicht verwendet werden, er wurde dem obigen Abschnitt zur Vollständigkeit hinzugefügt.
Example
Mein Paket enthält drei Assemblys, MyLib.dllMyHelpers.dll und MyUtilities.dll, die auf .NET Framework 4.7.2 ausgerichtet sind.
MyUtilities.dll enthält Klassen, die nur von den anderen beiden Assemblys verwendet werden sollen, daher möchte ich diese Klassen nicht in IntelliSense oder zur Kompilierungszeit für Projekte mit meinem Paket verfügbar machen. Meine nuspec Datei muss die folgenden XML-Elemente enthalten:
<references>
<group targetFramework="net472">
<reference file="MyLib.dll" />
<reference file="MyHelpers.dll" />
</group>
</references>
Ich muss sicherstellen, dass meine Paketinhalte:
lib\net472\MyLib.dll
lib\net472\MyHelpers.dll
lib\net472\MyUtilities.dll
ref\net472\MyLib.dll
ref\net472\MyHelpers.dll