Creare e distribuire librerie C# con NuGet

Creare e pubblicare librerie di classi su NuGet.org.

il
Sviluppatore / Ingegnere informatico / Funzionario, Collaboratore di IProgrammatori

In un precedente articolo abbiamo visto come si fa a installare e utilizzare una libreria distribuita con NuGet. Siccome è una modalità di distribuzione molto comoda e attraente anche per uno sviluppatore indipendente, potremmo chiederci come si fa a creare una libreria e soprattutto come si fa a metterla a disposizione di altri sviluppatori attraverso il portale NuGet. In questo articolo vedremo proprio come ottenere questo risultato.

Un esempio di libreria

Supponiamo di non aver trovato su NuGet una libreria per verificare formalmente il codice di partita IVA italiano e quindi decidiamo di crearcela da soli e poi di pubblicarla su NuGet a vantaggio di altri sviluppatori.

Creiamo una nuova soluzione e come template di progetto, per semplicità didattica, selezioniamo “Libreria di classi”, con il linguaggio C# e con .NET Standard 2.1. Questa scelta ci permette di rendere disponibile la libreria non solo per Windows, ma anche per le piattaforme Android, Linux e macOS.

Il codice che proponiamo è il seguente:

using System;

namespace ItalianVAT
{
public class VATcode
{
private string _code = "";

// restituisce il codice della partita IVA
public string italianVATcode
{
get
{
return _code;
}
}

// memorizza il codice della partita IVA se ha una lunghezza
// compresa tra 10 e 11:
// - 10 è la lunghezza senza il codice di controllo
// - 11 è la lunghezza completa
public bool SetCodeIVA(string code)
{
if (code.Length == 11)
{
if (CheckCode(code) == true & CheckProvince(code) == true)
{
_code = code;
return true;
}
else
{
_code = "";
return false;
}
}
else if (code.Length == 10 & CheckProvince(code) == true)
{
_code = CalculateItalianVATcode(code);
return true;
}
else
{
_code = "";
return false;
}
}

private string CalculateItalianVATcode(string code)
{
return code.Substring(0, 10) + CalculateCheckCode(code);
}

private string CalculateCheckCode(string code)
{
return CodeLuhn(code).ToString();
}

private bool CheckCode(string code)
{
string chkCodice = code.Substring(10, 1);
string chkLuhn = CodeLuhn(code).ToString();
if (chkCodice == chkLuhn)
return true;
else
return false;
}

private int CodeLuhn(string code)
{
int i;
int sum = 0;
int toSum;
int singleStep;
int doubled;

for (i = 0; i <= 9; i++)
{
singleStep = Convert.ToInt32(code.Substring(i, 1));
if ((i % 2) != 0)
{
doubled = singleStep * 2;
if (doubled >= 10)
toSum = 1 + (doubled % 10); // somma le cifre se il numero è > 10
else
toSum = doubled;
}
else
toSum = singleStep;
sum = sum + toSum;
}
if (sum % 10 == 0)
return 0;
else
return (10 - (sum % 10));
}

private bool CheckProvince(string code)
{
int provinceCode = Convert.ToInt32(GetCodeProvince(code));
if (provinceCode >= 1 & provinceCode <= 103 | provinceCode >= 108 & provinceCode <= 111)
return true;
else
return false;
}

private string GetCodeProvince(string code)
{
return code.Substring(7, 3);
}
}
}

Questo codice permette di verificare la correttezza di un codice di partita IVA completo, quindi di 11 cifre, secondo la formula di Luhn (https://it.wikipedia.org/wiki/Formula_di_Luhn). Permette anche di controllare se il codice di provincia (tre cifre posizionate dall’ottava alla decima cifra) è esistente. Se invece viene inserito un codice di 10 cifre, restituisce un codice completo del codice di controllo costituito dall’undicesima cifra.

Il procedimento per utilizzare questa classe è molto semplice:

  • create un oggetto di tipo ItalianVAT.VATcode;
  • passate all’oggetto un codice di 10 o 11 cifre con il metodo SetCodeIVA e leggete il valore logico di ritorno: se è true allora il codice è valido, se è false allora non è valido;
  • inoltre, se avete passato un codice di 10 cifre, per avere il codice completo a 11 cifre potrete leggere la proprietà italianVATcode.

Ma ora veniamo al punto che costituisce l’obiettivo di questo articolo: la pubblicazione su NuGet.

Creare un pacchetto per NuGet

La prima cosa da fare è assegnare un identificativo univoco al pacchetto, cioè dobbiamo dare un nome univoco (non esistente in NuGet) al nostro assembly. Per questa operazione:

  1. cliccate con il tasto destro del mouse sul nome del progetto e selezionate Proprietà;
  2. spostatevi alla sezione Pacchetto > Generale e trovate la voce ID pacchetto: qui scriveremo, per il nostro esempio, “ItalianVAT” al posto del default $(AssemblyName). L’identificativo non deve contenere spazi e, in generale, deve rispettare le regole di nomenclatura dei namespace di .NET;
  3. appena avrete modificato il nome del pacchetto e salvato le proprietà, potreste anche attivare la casella di spunta Genera pacchetto NuGet durante la compilazione che si trova appena sopra alla proprietà ID pacchetto: come è facile intuire, questo automatizzerà la produzione del pacchetto per NuGet, preparando più rapidamente il pacchetto da pubblicare;
  4. salvate le proprietà, modificate la configurazione della compilazione da Debug a Release e compilate. Nella sottocartella Release del progetto troverete il file ItalianVAT.1.0.0.nupkg che è il pacchetto da pubblicare (1.0.0 è la versione iniziale, ma nelle ricompilazioni e pubblicazioni successive dovete aggiornare la versione, perché NuGet non accetta nuovi pacchetti con lo stesso numero di versione).

Se ora provate a caricare il pacchetto, otterrete una segnalazione di un problema, cioè la mancanza del riferimento alla licenza d’uso che è obbligatoria per tutti i pacchetti.

L’elenco di tutti i tipi di licenza, con l’identificatore e con il link alla pagina con la licenza, potete trovarlo qui: https://spdx.org/licenses/. Per esempio, se decidete di utilizzare la licenza “GNU General Public License v3.0 or later”, dovete copiare l’identificatore “GPL-3.0-or-later” e inserirlo nelle proprietà del progetto, sezione Pacchetto > Licenza, campo Espressione di licenza.

Ora il tentativo di caricamento in NuGet andrà a buon fine, ma ovviamente ci saranno diverse informazioni che sarebbe opportuno completare per avere maggiori probabilità di ottenere un positivo riscontro da parte degli sviluppatori: per esempio la versione del pacchetto, il nome dell’autore, una descrizione, una eventuale URL del progetto, una icona del pacchetto (altrimenti verrà messa una icona di default), la lingua dell’assembly (nel nostro caso l’italiano) e così via.

Pubblichiamo il pacchetto su NuGet

Aprite la pagina https://www.nuget.org/ nel vostro browser ed effettuate l’accesso con il profilo che avete registrato nel portale di Microsoft (la coppia utente/password eventualmente creata direttamente nel sito NuGet.org stanno a breve non sarà più utilizzabile).

Cliccate sul link Upload nel menu presente nella riga più in alto: ora siete nella pagina che vi permette di pubblicare i pacchetti NuGet. Cliccate sul pulsante Browse…, selezionate il pacchetto da pubblicare, verificate se ci sono eventuali segnalazioni di errore e poi cliccate su Submit per caricare il pacchetto.

Per la pubblicazione vera e propria occorre attendere mediamente un’ora (talvolta meno, in altri casi molto di più), dato che il pacchetto deve passare alcune fasi di validazione e di indicizzazione per poter essere visibile alle ricerche e per poter essere installabile. Nel nostro caso, il pacchetto è già disponibile dopo pochi minuti (https://www.nuget.org/packages/ItalianVAT).

Come si usa?

L’utilizzo della libreria è semplice e, per le operazioni da eseguire, vi rinviamo all’articolo precedente. Per il codice, invece, potrete utilizzare qualcosa di simile a questo (per esempio nel gestore dell’evento Click di un pulsante in Windows Forms):

private void button1_Click(object sender, EventArgs e)
{
  ItalianVAT.VATcode VAT = new ItalianVAT.VATcode();
  bool esito = VAT.SetCodeIVA("00300650256");
  MessageBox.Show(esito.ToString());
}

Conclusione

In questo articolo abbiamo visto come la creazione di librerie di uso generale può essere di aiuto a molti altri sviluppatori, attraverso la pubblicazione sul portale NuGet.org.

La filosofia di molti sviluppatori è basata spesso su un modello di condivisione del lavoro, perché la programmazione è un lavoro intellettuale che richiede molto studio individuale, ma le migliori soluzioni si condividono per rendere il lavoro più facile agli altri. Se noi aiutiamo gli altri programmatori con le soluzioni che ci riescono bene, verrà spesso il momento in cui anche noi avremo bisogno dell’aiuto di altri che hanno risolto lo stesso problema, con soddisfazione da parte di tutti. Infatti, quando il gioco si fa duro, da soli si fa poco, mentre in squadra si vince!