Creare un pacchetto NuGet usando MSBuild

Quando si crea un pacchetto NuGet dal codice, si rendono disponibili tali funzionalità in un componente condivisibile e utilizzabile da altri sviluppatori. Questo articolo descrive come creare un pacchetto usando MSBuild. MSBuild viene preinstallato con tutti i carichi di lavoro di Visual Studio che contengono NuGet. È anche possibile usare MSBuild tramite l'interfaccia della riga di comando dotnet con dotnet msbuild.

Per i progetti .NET Core e .NET Standard che usano il formato di tipo SDK, e qualsiasi altro progetto di tipo SDK, NuGet usa le informazioni nel file di progetto direttamente per creare un pacchetto. Anche per un progetto di tipo non SDK che usa <PackageReference>, NuGet usa il file di progetto per creare un pacchetto.

Nei progetti di tipo SDK la funzionalità pack è disponibile per impostazione predefinita. Per i progetti PackageReference di tipo non SDK, è necessario aggiungere il pacchetto NuGet.Build.Tasks.Pack alle dipendenze del progetto. Per informazioni dettagliate sulle destinazioni pack MSBuild, vedere Pack e restore di NuGet come destinazioni MSBuild.

Il comando che crea un pacchetto, msbuild -t:pack, è funzionalmente equivalente a dotnet pack.

Importante

Questo argomento si applica ai progetti di tipo SDK, in genere progetti .NET Core e .NET Standard, e ai progetti di tipo non SDK che usano PackageReference.

Impostare le proprietà

Per creare un pacchetto, sono necessarie le proprietà seguenti.

  • PackageId, ovvero l'identificatore del pacchetto, che deve essere univoco nella raccolta che ospita il pacchetto. Se non è specificato, il valore predefinito è AssemblyName.
  • Version, ovvero un numero di versione specifico nel formato Principale.Secondaria.Patch[-Suffisso] dove -Suffisso identifica le versioni preliminari. Se non è specificato, il valore predefinito è 1.0.0.
  • Titolo del pacchetto come deve essere visualizzato nell'host (ad esempio, nuget.org)
  • Authors, ovvero informazioni sull'autore e sul proprietario. Se non è specificato, il valore predefinito è AssemblyName.
  • Company, ovvero il nome della società. Se non è specificato, il valore predefinito è AssemblyName.

Inoltre, se si esegue il pacchetto di progetti non in stile SDK che usano PackageReference, è necessario quanto segue:

  • PackageOutputPath, la cartella di output per il pacchetto generato durante la chiamata al pacchetto.

In Visual Studio è possibile impostare questi valori nelle proprietà del progetto (fare clic con il pulsante destro del mouse sul progetto in Esplora soluzioni, scegliere Proprietà e selezionare la scheda Pacchetto). È anche possibile impostare queste proprietà direttamente nei file di progetto (con estensione csproj).

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

Importante

Assegnare al pacchetto un identificatore univoco in nuget.org o per l'origine di pacchetti in uso.

L'esempio seguente illustra un file di progetto semplice e completo con queste proprietà incluse.

<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>

È anche possibile impostare le proprietà facoltative, ad esempio Title, PackageDescription e PackageTags, come descritto in Destinazioni di pack per MSBuild, Controllo degli asset delle dipendenze e Proprietà dei metadati NuGet.

Nota

Per i pacchetti compilati per uso pubblico, prestare particolare attenzione alla proprietà PackageTags, perché questi tag consentono ad altri utenti di trovare il pacchetto e di comprenderne le funzioni.

Per informazioni dettagliate sulla dichiarazione delle dipendenze e sulla specifica dei numeri di versione, vedere Riferimenti ai pacchetti nei file di progetto e Controllo delle versioni dei pacchetti. È anche possibile esporre gli asset dalle dipendenze direttamente nel pacchetto usando gli attributi <IncludeAssets> e <ExcludeAssets>. Per altre informazioni, vedere Controllo degli asset delle dipendenze.

Aggiungere un campo di descrizione facoltativo

La descrizione facoltativa del pacchetto viene visualizzata nella scheda LEGGIMI della pagina nuget.org del pacchetto. La descrizione estrae da <Description> nel file di progetto o $description nel file con estensione nuspec.

L'esempio seguente mostra un Description oggetto nel file con estensione csproj per un pacchetto .NET:

<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>

Scegliere un identificatore univoco del pacchetto e impostare il numero di versione

L'identificatore del pacchetto e il numero di versione identificano in modo univoco il codice esatto contenuto nel pacchetto.

Seguire queste procedure consigliate per creare l'identificatore del pacchetto:

  • L'identificatore deve essere univoco tra nuget.org e tutte le altre posizioni che ospitano il pacchetto. Per evitare conflitti, un modello valido consiste nell'usare il nome della società come prima parte dell'identificatore.

  • Seguire una convenzione di denominazione simile allo spazio dei nomi .NET usando la notazione punto. Usare, ad esempio, Contoso.Utility.UsefulStuff invece di Contoso-Utility-UsefulStuff o Contoso_Utility_UsefulStuff. È anche utile per i consumer se si trova la corrispondenza tra l'identificatore del pacchetto e lo spazio dei nomi usato dal codice.

  • Se si produce un pacchetto di codice di esempio che illustra come usare un altro pacchetto, aggiungere .Sample all'identificatore, come in Contoso.Utility.UsefulStuff.Sample.

    Il pacchetto di esempio ha una dipendenza dal pacchetto originale. Quando si crea il pacchetto di esempio, aggiungere <IncludeAssets> con il contentFiles valore . Nella cartella del contenuto disporre il codice di esempio in una cartella denominata \Samples\<identifier>, ad esempio \Samples\Contoso.Utility.UsefulStuff.Sample.

Seguire queste procedure consigliate per impostare la versione del pacchetto:

  • In generale, impostare la versione del pacchetto in modo che corrisponda alla versione del progetto o dell'assembly, anche se non è strettamente necessaria. La corrispondenza della versione è semplice quando si limita un pacchetto a un singolo assembly. NuGet gestisce autonomamente le versioni dei pacchetti durante la risoluzione delle dipendenze, non le versioni degli assembly.

  • Se si usa uno schema di versione non standard, assicurarsi di prendere in considerazione le regole di controllo delle versioni di NuGet, come illustrato in Controllo delle versioni dei pacchetti. NuGet è principalmente conforme al controllo delle versioni semantiche 2.0.0.

Nota

Per altre informazioni sulla risoluzione delle dipendenze, vedere Risoluzione delle dipendenze con PackageReference. Per informazioni utili per comprendere il controllo delle versioni, vedere questa serie di post di blog:

Aggiungere il pacchetto NuGet.Build.Tasks.Pack

Se si usa MSBuild con un progetto di tipo non SDK e PackageReference, aggiungere il pacchetto NuGet.Build.Tasks.Pack al progetto.

  1. Aprire il file di progetto e aggiungere quanto segue dopo l'elemento <PropertyGroup>:

    <ItemGroup>
      <!-- ... -->
      <PackageReference Include="NuGet.Build.Tasks.Pack" Version="6.7.0" PrivateAssets="all" />
      <!-- ... -->
    </ItemGroup>
    
  2. Aprire un prompt dei comandi per gli sviluppatori digitando Prompt dei comandi per gli sviluppatori nella casella Cerca.

    In genere, è consigliabile avviare il prompt dei comandi per gli sviluppatori per Visual Studio dal menu Start, in modo che venga configurato con tutti i percorsi necessari per MSBuild.

  3. Passare alla cartella contenente il file di progetto e digitare il comando seguente per installare il pacchetto NuGet.Build.Tasks.Pack.

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

    Verificare che l'output di MSBuild indichi che la compilazione è stata completata correttamente.

Eseguire il comando msbuild -t:pack

Per compilare un pacchetto NuGet (un file .nupkg) dal progetto, eseguire il comando msbuild -t:pack, che consente anche di compilare automaticamente il progetto:

Al prompt dei comandi per gli sviluppatori per Visual Studio digitare il comando seguente:

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

L'output mostra il percorso del file .nupkg.

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

Generare automaticamente il pacchetto in fase di compilazione

Per eseguire automaticamente msbuild -t:pack quando si compila o si ripristina il progetto, aggiungere la riga seguente al file di progetto all'interno di <PropertyGroup>:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

Quando si esegue msbuild -t:pack per una soluzione, vengono inseriti nel pacchetto tutti i progetti nella soluzione che supportano i pacchetti (proprietà <IsPackable> impostata su true).

Nota

Quando si genera automaticamente il pacchetto, il tempo di creazione del pacchetto aumenta il tempo di compilazione per il progetto.

Testare l'installazione del pacchetto

Prima di pubblicare un pacchetto, in genere si preferisce testarne il processo di installazione in un progetto. I test assicurano che i file necessari vengano inseriti nei percorsi corretti all'interno del progetto.

È possibile testare manualmente le installazioni in Visual Studio o dalla riga di comando seguendo i normali passaggi di installazione del pacchetto.

Importante

I pacchetti non sono modificabili. Se si corregge un problema, modificare il contenuto del pacchetto e crearlo di nuovo. Quando si ripetono i test verrà comunque usata la versione precedente del pacchetto fino a quando non si cancella la cartella dei pacchetti globali. Questo aspetto è particolarmente importante quando si testano pacchetti che non usano un'etichetta di versione preliminare univoca per ogni compilazione.

Passaggi successivi

Dopo aver creato un pacchetto, ovvero un file .nupkg, è possibile pubblicarlo nella raccolta di propria scelta, come descritto in Pubblicazione di un pacchetto.

Potrebbe anche essere necessario estendere le funzionalità del pacchetto o supportare altri scenari, come descritto negli argomenti seguenti:

Sono infine disponibili altri tipi di pacchetti da tenere presenti: