blexin

Sviluppo
Consulenza e
Formazione IT


Blog

Evolvi la tua azienda

Vediamo insieme cinque metodi per abilitare il debug delle nostre librerie NuGet

Come debuggare le librerie NuGet

Mercoledì 6 Maggio 2020

Qualche settimana fa ho cominciato a fare dirette su twitch, e mi è stata fatta questa domanda: come posso fare in maniera semplice il debug delle mie librerie NuGet?

In questo blog, ho già parlato altre volte di come creare e assegnare una versione ad un pacchetto NuGet, ma in questo post voglio mostrarvi come effettuare il debug delle librerie dopo il rilascio.

Sono fortemente convinto che la seguente lista non è completa, e sicuramente ci sono tanti altri modi per raggiungere lo stesso scopo, ma questi sono quelli che ho provato nella mia esperienza lavorativa:

  • NuGet Remote Server + Symbol files (PDB)
  • NuGet Local Server + Symbol files (PDB)
  • Package Reference Switcher (Estensione per Visual Studio)
  • Sostituzione dei riferimenti con uno script PowerShell
  • Referenziare direttamente la DLL

Diamo un’occhiata ad ogni soluzione nel dettaglio. In questo scenario, ipotizziamo che tu abbia la necessità di fare il debug e risolvere un bug in un pacchetto NuGet. Ipotizziamo inoltre che tu abbia accesso sia al codice sorgente della libreria che del progetto che la referenzia come package, ma entrambi non si trovano nella stessa soluzione di Visual Studio.

NuGet Remote Server + Symbol files (PDB)

Durante la creazione del pacchetto NuGet, è possibile generare anche i file dei simboli. Se non li conosci, una buona definizione è la seguente (dalla documentazione Microsoft):

“Program database (.pdb) files, also called symbol files, map identifiers, and statements in your project's source code to corresponding identifiers and instructions in compiled apps.”

I file dei simboli aiutano a fare debug del codice perché mappano il codice sorgente con la propria versione compilata, favorendo lo step-by-step al suo interno quando un breakpoint è impostato.

Ci sono diversi modi per creare un file di simboli, per esempio, se usi la .NET Core CLI, il comando pack può generare un Symbol Package (.snupkg) che contiene il file PDB con i seguenti parametri:

dotnet pack MyPackage.csproj -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg

Una volta creato, un file PDB deve essere disponibile per il debugging usando un Symbol Server o spostando il file direttamente nella cartella bin del progetto che referenzia la libreria. Il primo approccio è maggiormente affidabile, soprattutto se si usa un sistema di CI/CD come Azure DevOps. In questo caso, la pipeline pubblica sia il pacchetto che il file dei simboli (nota: Azure Artifacts ha integrato un Symbol Server). Un’altra cosa interessante è che questi file PDB sono cross-platform (dai un occhio qui per maggiori info)!

Per fare poi il debug della libreria, occorre aggiungere il puntamento al Symbol Server in Visual Studio come spiegato qui.

Figura 1: Aggiungere un symbol server in Visual Studio

Una volta riscontrato un bug, occorre sistemare il codice nella libreria e effettuare il commit delle modifiche nel codice sorgente. Questa azione fa scattare la pipeline di build per creare nuovamente sia il pacchetto che il file dei simboli, caricandoli su un server NuGet di tua scelta. Infine, occorre aggiornare la dipendenza nel progetto che la referenzia.

Nonostante questo processo sia molto affidabile, lanciare una build per generare un pacchetto, specialmente se non è stato testato completamente, può rallentare il processo di sviluppo. Il prossimo paragrafo spiega come affrontare questo problema.

NuGet Local Server + Symbol files (PDB)

Sapevi che un server Nuget può essere creato da una cartella locale? Nel caso in cui non lo sapevi, questi sono gli step necessari:

  1. Creare la cartella;
  2. Eseguire il comando nuget sources add -Name LocalNuget -Source <local-nuget-folder> per aggiungere una sorgente NuGet;
  3. Caricare il pacchetto con il comando dotnet nuget push <nupkg-files> -s <local-nuget-folder>;
  4. Aggiungere il pacchetto aggiornato al progetto che lo referenzia.

L’aspetto noioso è che, per effettuare il debug del codice, occorre copiare manualmente il file PDB nella cartella del progetto che viene eseguito. Inoltre, la differenza principale con l’approccio visto nel paragrafo precedente è che la pipeline di CI/CD non parte fino a che tutte le fix sono completate.

Package Reference Switcher (Extension)

Package Reference Switcher è una estensione per Visual Studio che consente di sostituire un pacchetto Nuget con un progetto (.csproj) e viceversa. L’estensione è disponibile qui: https://marketplace.visualstudio.com/items?itemName=RicoSuter.NuGetReferenceSwitcherforVisualStudio2019.Dopo averla installata in Visual Studio, occorre andare in Tools e selezionare “Switch NuGet and Project references”, che apre una finestra per cambiare i riferimenti. È possibile sostituire un pacchetto NuGet usando un progetto nella stessa soluzione oppure da qualsiasi altra parte sul proprio PC. Una volta completato il testing, è possibile ritornare al riferimento del pacchetto NuGet, aggiornandolo se necessario.

Figura 2: L’opzione Package Reference Switcher in Visual Studio

Figura 3: Sostituzione di un riferimento con Package Reference Switcher

Questa estensione è molto utile, anche se ho notato che non supporta completamente i progetti .NET Core (compare un errore in fase di sostituzione). Infatti l’autore stesso suggerisce di utilizzare un altro suo progetto, che anticipa in parte anche la soluzione che vedremo nel prossimo paragrafo: https://github.com/RicoSuter/DNT (il nome dell’autore ricorda qualcosa?). Si tratta di una utility da terminale per gestire i pacchetti e riferimenti e supporta i progetti .NET Core.

Sostituzione dei riferimenti con uno script PowerShell

Package Reference Switcher ha risvegliato in me la passione per PowerShell. In pratica, l’idea dietro questo approccio è semplice, e grazie alla .NET Core CLI, posso ottenere lo stesso scopo in pochi minuti. Quello che mi serve sapere è:

  • Posizione del progetto della libreria
  • Posizione della soluzione
  • Posizione del progetto che referenzia la libreria
  • Nome del package
  • Qualche comando della .NET Core CLI

Un esempio di script potrebbe essere il seguente:

Switch-Reference.ps1
param(
    [switch]$ToReferences
)
if($ToReferences)
{
    # Add the library project to the solution
    dotnet sln <solution_file> add <library_project_file>
    # Add the library reference to the executable project
    dotnet add <executable_project_file> reference <library_project_file>
    # Remove the NuGet package reference
    dotnet remove <executable_project_file> package <package_name>
}
else
{
    # Remove the library from solution
    dotnet sln <solution_file> remove <library_project_file> 
    # Remove the library reference
    dotnet remove <executable_project_file> reference <library_project_file>
    # Restore the NuGet package reference
    dotnet add <executable_project_file> package <package_name>
}

Durante l’esecuzione, posso sostituire un progetto con il pacchetto usando il parametro “-ToReference”.

Nonostante l’effort iniziale di configurazione dei comandi, trovo questo script molto pratico.

Referenziare direttamente la DLL

L’ultimo approccio consiste nel sostituire manualmente il pacchetto NuGet con il riferimento al progetto, o persino referenziare la DLL direttamente dalla cartella bin del progetto della libreria. Ad essere onesto, sono contro questo approccio. Si tratta di un approccio che potrebbe portare problemi introducendo comportamenti inaspettati o riferimenti sbagliati.

Quale metodo dovrei usare?

Quindi, riepilogando:

Personalmente, preferisco la prima soluzione se ci sono più progetti di cui effettuare il debug (e magari non sono io lo sviluppatore) o, se lo scenario è semplice, lo script PowerShell. Qualche volta mi piace unire i due approcci.

Happy debug!

ISCRIVITI ALLA NEWSLETTER

Autore

Servizi

Evolvi la tua azienda