Ein NuGet-Paket mit MSBuild erstellen

Wenn Sie ein NuGet-Paket aus Ihrem Code erstellen, verpacken Sie diese Funktionalität in eine Komponente, die mit einer beliebigen Anzahl anderer Entwickler geteilt und von diesen verwendet werden kann. In diesem Artikel wird das Erstellen eines Pakets mithilfe von MSBuild beschrieben. MSBuild wird mit allen Visual Studio-Workloads vorinstalliert, die NuGet enthalten. Zusätzlich können Sie MSBuild auch über die dotnet CLI mit dotnet msbuild verwenden.

Für .NET Core- und .NET Standard-Projekte, die das SDK-Format verwenden, und für alle anderen Projekte im SDK-Format verwendet NuGet Informationen in der Projektdatei direkt zum Erstellen eines Pakets. Für ein Projekt im Nicht-SDK-Stil, das <PackageReference> verwendet, verwendet NuGet auch die Projektdatei, um ein Paket zu erstellen.

Für Projekte im SDK-Stil ist die Packfunktionalität standardmäßig verfügbar. Für PackageReference-Projekte, die nicht im SDK-Stil erstellt werden, müssen Sie den Projektabhängigkeiten das Paket NuGet.Build.Tasks.Pack hinzufügen. Ausführliche Informationen zu MSBuild-Packzielen finden Sie unter NuGet-Befehle „pack“ und „restore“ als MSBuild-Ziele.

Der Befehl, mit dem ein Paket erstellt wird (msbuild -t:pack), ist funktional äquivalent mit dotnet pack.

Wichtig

Dieses Thema gilt für Projekte im SDK-Stil, in der Regel .NET Core- und .NET Standard-Projekte, und für Projekte im Nicht-SDK-Stil, die PackageReference verwenden.

Eigenschaften festlegen

Die folgenden Eigenschaften sind für die Erstellung eines Pakets erforderlich.

  • PackageId, der Paketbezeichner. Dieser muss im Katalog, der das Paket hostet, eindeutig sein. Wenn Sie hier nichts angeben, lautet der Standardwert AssemblyName.
  • Version, eine bestimmte Versionsnummer in der Schreibweise Hauptversion.Nebenversion.Patch[-Suffix], wobei im -Suffix die Vorabversionen angegeben werden. Wenn Sie hier nichts angeben, lautet der Standardwert 1.0.0.
  • Der Titel des Pakets, so wie er auf dem Host (z.B. „nuget.org“) angezeigt werden sollte
  • Authors, Informationen zum Autor und Besitzer. Wenn Sie hier nichts angeben, lautet der Standardwert AssemblyName.
  • Company, der Firmenname. Wenn Sie hier nichts angeben, lautet der Standardwert AssemblyName.

Wenn Sie Nicht-SDK-Projekte packen, die PackageReference verwenden, ist außerdem Folgendes erforderlich:

  • PackageOutputPath, der Ausgabeordner für das Paket, das beim Paketaufruf generiert wird.

In Visual Studio können Sie diese Werte in den Projekteigenschaften festlegen (Rechtsklick auf das Projekt im Projektmappen-Explorer, wählen Sie Eigenschaften und dann die Registerkarte Paket aus). Sie können diese Eigenschaften auch direkt in den Projektdateien festlegen (.csproj).

<PropertyGroup>
  <PackageId>ClassLibDotNetStandard</PackageId>
  <Version>1.0.0</Version>
  <Authors>your_name</Authors>
  <Company>your_company</Company>
</PropertyGroup>

Wichtig

Weisen Sie dem Paket einen Bezeichner zu, der auf nuget.org bzw. in der Paketquelle, den Sie verwenden, einzigartig ist.

Das folgende Beispiel zeigt eine einfache, vollständige Projektdatei, in der diese Eigenschaften enthalten sind.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <PackageId>ClassLibDotNetStandard</PackageId>
    <Version>1.0.0</Version>
    <Authors>your_name</Authors>
    <Company>your_company</Company>
  </PropertyGroup>
</Project>

Sie können auch die optionalen Eigenschaften wie Title, PackageDescription und PackageTags festlegen, wie in MSBuild-Paketziele, Steuern von Abhängigkeitsobjekten und NuGet-Metadateneigenschaften beschrieben.

Hinweis

Bei Paketen für die öffentliche Nutzung sollten Sie besonders auf die PackageTags-Eigenschaft achten, da Tags anderen dabei helfen, Ihr Paket zu finden und dessen Funktion zu verstehen.

Weitere Informationen zum Deklarieren von Abhängigkeiten und zum Angeben von Versionsnummern finden Sie unter Paketverweise in Projektdateien und Paketversionsverwaltung. Es ist auch möglich, Ressourcen aus Abhängigkeiten mithilfe der Attribute <IncludeAssets> und <ExcludeAssets> direkt im Paket verfügbar zu machen. Weitere Informationen finden Sie unter Steuern von Abhängigkeitsobjekten.

Hinzufügen eines optionalen Beschreibungsfelds

Die optionale Beschreibung des Pakets wird auf der Registerkarte README der nuget.org Seite des Pakets angezeigt. Die Beschreibung wird aus <Description> in der Projektdatei oder $description in der .nuspec-Datei abgerufen.

Das folgende Beispiel zeigt eine Description in der .csproj-Datei für ein .NET-Paket:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <PackageId>Azure.Storage.Blobs</PackageId>
    <Version>12.4.0</Version>
    <PackageTags>Microsoft Azure Storage Blobs;Microsoft;Azure;Blobs;Blob;Storage;StorageScalable</PackageTags>
    <Description>
      This client library enables working with the Microsoft Azure Storage Blob service for storing binary and text data.
      For this release see notes - https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/README.md and https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/CHANGELOG.md
      in addition to the breaking changes https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Azure.Storage.Blobs/BreakingChanges.txt
      Microsoft Azure Storage quickstarts and tutorials - https://learn.microsoft.com/azure/storage/
      Microsoft Azure Storage REST API Reference - https://learn.microsoft.com/rest/api/storageservices/
      REST API Reference for Blob Service - https://learn.microsoft.com/rest/api/storageservices/blob-service-rest-api
    </Description>
  </PropertyGroup>
</Project>

Auswählen eines eindeutigen Paketbezeichners und Festlegen der Versionsnummer

Der Paketbezeichner und die Versionsnummer bezeichnen eindeutig den exakten Code, der im Paket enthalten ist.

Befolgen Sie die folgenden bewährten Methoden zum Erstellen des Paketbezeichners:

  • Der Bezeichner muss für nuget.org und alle anderen Speicherorte, die das Paket hosten, eindeutig sein. Zur Vermeidung von Konflikten empfiehlt es sich, den Namen Ihres Unternehmens im ersten Teil des Bezeichners zu nutzen.

  • Folgen Sie einer .NET-Namespace-ähnlichen Benennungskonvention mit Punktnotation. Schreiben Sie z.B. Contoso.Utility.UsefulStuff statt Contoso-Utility-UsefulStuff oder Contoso_Utility_UsefulStuff. Es ist auch für Verbraucher hilfreich, wenn Sie den Paketbezeichner mit dem Namespace abgleichen, den der Code verwendet.

  • Wenn Sie ein Paket mit Beispielcode erstellen, das veranschaulicht, wie ein anderes Paket verwendet wird, fügen Sie .Sample als Suffix an den Bezeichner an, wie in Contoso.Utility.UsefulStuff.Sample.

    Das Beispielpaket hat eine Abhängigkeit vom ursprünglichen Paket. Fügen Sie beim Erstellen des Beispielpakets <IncludeAssets> mit dem Wert contentFiles hinzu. Ordnen Sie im Inhaltsordner den Beispielcode in einem Ordner namens \Samples\<identifier> an, z. B. \Samples\Contoso.Utility.UsefulStuff.Sample.

Befolgen Sie die folgenden bewährten Methoden zum Festlegen der Paketversion:

  • Im Allgemeinen sollten Sie die Paketversion so einstellen, dass sie mit der Projekt- oder Assembly-Version übereinstimmt, obwohl dies nicht zwingend erforderlich ist. Die Anpassung der Version ist einfach, wenn Sie ein Paket auf eine einzige Baugruppe beschränken. NuGet selbst richtet sich beim Auflösen der Abhängigkeiten nach den Paketversionen, nicht nach den Assemblyversionen.

  • Wenn Sie ein nicht standardmäßiges Versionsschema verwenden, müssen Sie die NuGet-Versionsregeln wie unter Paketversionsverwaltung beschrieben anwenden. NuGet ist größtenteils Semantic Versioning 2.0.0-kompatibel.

Hinweis

Weitere Informationen zur Abhängigkeitsauflösung finden Sie unter Abhängigkeitsauflösung mit PackageReference. Informationen, die möglicherweise hilfreich sein können, um die Versionierung besser zu verstehen, finden Sie in dieser Reihe von Blog-Einträgen.

Hinzufügen des Pakets NuGet.Build.Tasks.Pack

Wenn Sie MSBuild mit einem Projekt im Nicht-SDK-Stil und PackageReference verwenden, fügen Sie Ihrem Projekt das Paket NuGet.Build.Tasks.Pack hinzu.

  1. Öffnen Sie die Projektdatei, und fügen Sie Folgendes hinter dem <PropertyGroup>-Element hinzu:

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" />
      <!-- ... -->
    </ItemGroup>
    
  2. Öffnen Sie eine Developer-Eingabeaufforderung (geben Sie Developer-Eingabeaufforderung im Suchfeld ein).

    In der Regel sollten Sie die „Developer-Eingabeaufforderung für Visual Studio“ über das Startmenü starten, da dieses mit allen nötigen Pfaden für MSBuild konfiguriert ist.

  3. Wechseln Sie zu dem Ordner, der die Projektdatei enthält, und geben Sie den folgenden Befehl ein, um das Paket NuGet.Build.Tasks.Pack zu installieren.

    # Uses the project file in the current folder by default
    msbuild -t:restore
    

    Stellen Sie sicher, dass die MSBuild-Ausgabe angibt, dass der Build erfolgreich abgeschlossen wurde.

Ausführen des Befehls msbuild -t:pack

Um ein NuGet-Paket (eine .nupkg-Datei) aus dem Projekt zu erstellen, führen Sie den msbuild -t:pack-Befehl aus, der auch das Projekt automatisch erstellt:

Geben Sie an der Developer-Eingabeaufforderung für Visual Studio den folgenden Befehl ein:

# Uses the project file in the current folder by default
msbuild -t:pack

Die Ausgabe zeigt den Pfad zur .nupkg-Datei.

Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 8/5/2019 3:09:15 PM.
Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" on node 1 (pack target(s)).
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreCompile:
  ...
CopyFilesToOutputDirectory:
  Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.dll" to "C:\Use
  rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll".
  ClassLib_DotNetStandard -> C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.dll
  Copying file from "C:\Users\username\source\repos\ClassLib_DotNetStandard\obj\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb" to "C:\Use
  rs\username\source\repos\ClassLib_DotNetStandard\bin\Debug\netstandard2.0\ClassLib_DotNetStandard.pdb".
GenerateNuspec:
  Successfully created package 'C:\Users\username\source\repos\ClassLib_DotNetStandard\bin\Debug\AppLogger.1.0.0.nupkg'.
Done Building Project "C:\Users\username\source\repos\ClassLib_DotNetStandard\ClassLib_DotNetStandard.csproj" (pack target(s)).

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:01.21

Automatisches Generieren des Pakets bei der Erstellung

Um msbuild -t:pack automatisch auszuführen, wenn Sie das Projekt erstellen oder wiederherstellen, fügen Sie Ihrer Projektdatei in <PropertyGroup> die folgende Zeile hinzu:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

Wenn Sie msbuild -t:pack für eine Projektmappe ausführen, werden alle Projekte in der Projektmappe verpackt, die verpackt werden können (die Eigenschaft <IsPackable> wird auf true festgelegt).

Hinweis

Wenn Sie das Paket automatisch generieren, erhöht die Zeit zum Verpacken die Erstellungszeit für Ihr Projekt.

Testen der Paketinstallation

Vor dem Veröffentlichen eines Pakets testen Sie in der Regel die Installation eines Pakets in einem Projekt. Diese Tests stellen sicher, dass die erforderlichen Dateien an den richtigen Orten im Projekt installiert werden.

Installationen lassen sich manuell in Visual Studio oder mithilfe der normalen Paketinstallationsschritte über die Befehlszeile testen.

Wichtig

Pakete sind unveränderlich. Wenn Sie ein Problem beheben, ändern Sie den Inhalt des Pakets und verpacken Sie es erneut. Wenn Sie es erneut testen, verwenden Sie weiterhin die alte Version des Pakets, bis Sie Ihren Ordner für globale Pakete löschen. Dies ist besonders relevant, wenn Sie Pakete testen, die nicht bei jedem Build eine eindeutige Vorabversionsbezeichnung verwenden.

Nächste Schritte

Nachdem Sie ein Paket erstellt haben, das eine .nupkg-Datei ist, können Sie sie wie unter Publishing packages (Veröffentlichen von Paketen) beschrieben im Katalog Ihrer Wahl veröffentlichen.

Sie können auch die Funktionen des Pakets erweitern oder wie in den folgenden Themen beschrieben andere Szenarios unterstützen:

Außerdem sollten Sie die folgenden zusätzlichen Pakettypen berücksichtigen: