Aller au contenu
  1. Posts/

Créer une librairie NuGet

·1287 mots·7 mins

Que l’on soit seul ou en entreprise, dupliquer du code n’est jamais une bonne pratique. C’est l’une des premières règles en informatique : lorsqu’on crée quelque chose, on le réutilise, on le consolide, mais on évite de le recréer, sauf exception.

Notre objectif ici sera donc de créer des bibliothèques réutilisables et facilement intégrables dans n’importe quel projet ou autre bibliothèque.

Nous n’aborderons pas ici la question de l’obfuscation de code. Chaque package NuGet que nous créerons, contenant les DLL, sera potentiellement lisible par quiconque. Nous traiterons de l’obfuscation du code dans un autre article.

Pour simplifier, nous allons voir comment créer une bibliothèque NuGet à partir de code C# et la publier sur GitHub.

Cela vous permettra d’intégrer vos bibliothèques très facilement à l’aide de NuGet, comme vous le faites déjà pour n’importe quelle bibliothèque open source utilisée dans vos différents projets.

Découpage du code #

Avant de plonger dans le vif du sujet, faisons une petite aparté. La création d’un package NuGet implique la création d’une bibliothèque. Cette bibliothèque contiendra du code, code qui sera amené à évoluer et qui pourrait également avoir ses propres dépendances.

Je vous encourage vivement à bien structurer votre code, en suivant notamment la séparation standard que l’on retrouve dans .NET : une bibliothèque d’abstraction et une bibliothèque d’implémentation, comme par exemple :

  • MyLib.Abstractions
  • MyLib

La bibliothèque d’abstraction contiendra toutes les interfaces nécessaires au bon fonctionnement de votre bibliothèque d’implémentation, mais sans en connaître les détails. Cette implémentation sera réservée à la seconde bibliothèque. Ne vous inquiétez pas, nous verrons juste après une méthode permettant de publier une ou plusieurs bibliothèques sans problème.

Pour illustrer ce propos, voici un diagramme représentant un exemple de bibliothèque découpée en plusieurs sous-bibliothèques, respectant ainsi la séparation des rôles (principe SOLID), notamment la séparation des interfaces et des implémentations :

Exemple de séparation des librairies
Exemple de séparation des librairies

Prenons maintenant un exemple d’une librairie que vous devez connaître : Microsoft.Extensions.Logging. Il en existe plusieurs, chacune ayant leur role et notamment, dans notre exemple, Microsoft.Extensions.Logging.Abstractions. On retrouve bien les interfaces séparé des implémentations :

Exemple de séparation des librairies avec MS Logging
Exemple de séparation des librairies avec MS Logging

On voit bien ici que les implémentations Logger et LoggerFactory de la librairie Microsoft.Extensions.Logging héritent réciproquement de ILogger et ILoggerFactory d’une autre librairie Microsoft.Extensions.Logging.Abstractions.

Bien entendu la bibliothèque Microsoft.Extensions.Logging reférence Microsoft.Extensions.Logging.Abstractions comme un dépendance dans le cas présent. Ça sera la même chose pour nos propres librairies.

Création des package Nuget #

La création de packages NuGet est relativement simple. Grâce à la CLI .NET, vous pouvez générer tous vos packages NuGet en local ou sur votre CI de manière très simple.

Comme vous l’aurez compris, la plupart des instructions nécessaires ne se feront pas directement dans le code. Elles seront exécutées via le terminal ou la console avec des commandes .NET.

Pour plus de praticité et de scalabilité (utilisation en local et sur une CI), je vous propose d’utiliser un script batch permettant l’exécution automatique de la génération des packages NuGet :

while getopts v:k: flag
do
    case "${flag}" in
        v) version=${OPTARG};;
        k) key=${OPTARG};;
    esac
done

dotnet pack "MyLib.csproj" --configuration Release
dotnet pack "MyLib.Abstractions.csproj" --configuration Release

Ce script est relativement simple :

  • Il récupère en paramètres d’entrées la version et la clé à utilisé (on ne veut pas hardcodé la clé pour des raisons de sécurité)
  • Il utilise la commande dotnet pack pour chaque librairie

Il est maintenant possible de trouver votre fichier nupkg dans chaque dossier “bin/Release” de chacune de vos librairies.

Publication sur GitHub #

N’oubliez pas qu’il est tout à fait possible d’utiliser directement vos packages NuGet en local. Vous n’avez pas besoin de les publier sur un serveur (GitHub ou autre) si vous travaillez seul ou dans une petite équipe qui ne souhaite pas investir dans un serveur.

Cependant, dans ce guide, nous allons voir comment partager nos bibliothèques en privé au sein de notre organisation, afin que tous ceux qui travaillent avec nous puissent les utiliser.

Heureusement pour nous, GitHub offre toutes les fonctionnalités nécessaires pour cela.

Pour commencer, rendez-vous dans les paramètres de votre compte GitHub. Ensuite, allez dans “Developer settings”, puis dans “Personal access tokens” et enfin dans “Tokens (classic)”.

Github personal access tokens
Github personal access tokens

Nous allons maintenant créer un nouveau token. Il aura besoin à minima des permissions suivantes :

  • delete:packages
  • repo
  • write:packages

Pour des raisons évidentes de sécurité, il est fortement recommandé de créer des tokens avec le moins de persmission possible.

Vous l’aurez compris, il est nécessaire de bien sauvegarder la nouvelle clé générée. Si vous ne voulez pas avoir de soucis, a posteriori : impossible de publier, quelqu’un d’autre à publié à votre place, etc …

Je souligne un point évident : ne partagez jamais votre clé d’accès avec qui que ce soit, même au sein de votre organisation. Chaque utilisateur doit avoir sa propre clé.

Nous allons maintenant modifier le précédent script pour gérer la publication automatique sur GitHub :

dotnet nuget push "MyLib/bin/Release/MyLib.$version.nupkg" --api-key $key --source "myNuget"
dotnet nuget push "MyLib.Abstractions/bin/Release/MyLib.Abstractions.$version.nupkg" --api-key $key --source "myNuget"

La commande dotnet nuget push permet cette publication. Vous noterez qu’on utilise la paramètre –source avec cette commande. Elle permet de définir la cible du déploiement. Dans le cas présent il s’agit de notre serveur Github.

Mais avant d’executer à nouveau notre script, il est important d’expliquer à NuGet ce que représente myNuget. Pour cela, ajoutez à la racin de votre projet le fichier nuget.config :

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="myNuget" value="https://nuget.pkg.github.com/MyTeam/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="MyUsername" />
        </github>
    </packageSourceCredentials>
</configuration>
L’URL de votre dépôt NuGet se trouve être toujours être l’URL suivante “https://nuget.pkg.github.com” suffixé avec le nom de votre organisation et /index.json.

Vous pouvez maintenant executer à nouveau le script et constaté la présence de votre librairie directement sur votre compte Github !

Alors maintenant comment les utiliser ?

Utiliser une librairie custom via Nuget #

Pour ceux qui ne seraient pas familiers avec NuGet, il fonctionne de manière similaire à Maven et à d’autres gestionnaires de dépendances bien connus sur diverses plateformes. En d’autres termes, il existe des serveurs principaux gérés par des grandes entreprises et utilisés automatiquement par différents environnements de développement (IDE). Cependant, il est tout à fait possible d’ajouter nos propres sources et de configurer nos propres serveurs NuGet.

Nous allons donc ajouter une nouvelle source de données à notre IDE. Voici des exemples de configuration pour les deux principaux IDE.

Avec Visual Studio #

Avec Visual Studio c’est très simple. Rendez-vous dans les paramètres “Options” > “Gestionnaire de packages NuGet” et cliquer sur “+”

Paramètres Visual Studio
Paramètres Visual Studio

À partir il ne vous reste plus qu’à rentrer les différentes informations demandé et le tour est joué ! Dans le gestionnaire de package NuGet vous verrez votre nouvelle source :

Gestionnaire de package NuGet
Gestionnaire de package NuGet

Avec Rider #

Lorsque vous ouvrez votre gestionnaire de dépendances NuGet dans Rider, aller dans l’onglet “Sources”. Ce dernier va vous proposer une liste par défaut de configuration disponibles :

  • [Effective NuGet.Config]
  • Et votre propre configuration

C’est dans cette dernière que nous allons ajouter une nouvelle source. Sélectionné là et cliquer sur le bouton “+”.

Ajouter une source NuGet
Ajouter une source NuGet
Dans certains cas la source n’est pas activé par défaut, n’oubliez pas de cocher la case “Enable” pour l’utiliser.

Vous pouvez maintenant directement voir vos librairies dans votre manager NuGet :

Librairies dans le manager NuGet
Librairies dans le manager NuGet

En conclusion, la création et le partage de packages NuGet peuvent grandement faciliter la gestion des dépendances et la réutilisabilité de votre code, que vous travailliez seul ou en équipe. En suivant ces étapes et en adoptant de bonnes pratiques, vous pourrez optimiser vos workflows et améliorer la collaboration au sein de votre organisation.

En espérant que cet article vous aura plu, n’hésitez pas à le partager et à revenir nous voir plus tard !