La mise en place de l’organisation d’un projet est un processus fastidieux et non trivial. Contrairement à Java qui, avec Maven, propose une structure « standardisée », il n’y a pas de référence à ce sujet en .NET. Dans le billet précédent, nous avions parlé du découpage entre solutions et projets, dans celui-ci nous traiterons de la gestion des dépendances.
L’utilisation de librairies tierces est indispensable lors du développement d’un projet si on veut éviter de réinventer la roue à chaque fois. Comment gère-t-on ces librairies? Quelle est leur place dans la hiérarchie d’un projet C#? Comment les référencer?
En C# (.NET en général), une référence peut se faire vers les éléments suivants :
- Les assemblies du framework .NET (
System,System.Core…) - Les assemblies d’autres projets de la solution
- Des assemblies tierces
- Des composants COM
- Des web services XML
Nous nous concentrerons dans ce billet sur les références vers des projets de la solution et vers des librairies tierces.
Références entre projets
Dans une solution comprenant plusieurs projets, il est souvent utile de référencer les projets les uns aux autres. Ceci peut être effectué en utilisant des références de fichiers ou des références entre projets. Les références de fichiers sont des références directes aux assemblies alors que les références entre projets sont des références aux projets qui contiennent des assemblies.
Il faut toujours utiliser les références entre projets pour référencer des projets entre eux. Cela présente l’avantage de créer une dépendance entre les projets dans le système de build : le projet dépendant sera généré s’il a été modifié depuis la dernière génération du projet de référence. Au contraire, une référence de fichier ne crée pas de dépendance de build, et il est donc possible de générer le projet de référence sans générer le projet dépendant, il est alors possible de référencer une version obsolète du projet.
Librairies tierces
La question entre références de fichiers et références entre projets ne se pose pas en ce qui concerne les dépendances vers des librairies tierces : seules les références de fichiers sont possibles. Les assemblies peuvent être référencées à partir du GAC (Global Assembly Cache) ou directement sur le disque par le biais d’un chemin absolu ou relatif.
Nous déconseillons fortement de référencer des assemblies à partir du GAC, en effet un projet doit être facilement construit une fois récupéré du gestionnaire de source. Dans le cas où une référence est faite à partir du GAC, le développeur devra insérer l’assembly manquante dans celui-ci avant de pouvoir construire le projet. A l’origine le GAC a été conçu pour être utilisé à l’exécution et non pas au développement.
A la place, nous recommandons de regrouper toutes les librairies tierces dans un dossier à la racine de la solution, sous contrôle du gestionnaire de sources, et d’utiliser un chemin relatif pour la référence (e.g: <Hintpath>../lib/nunit.dll</Hintpath> dans le fichier csproj). De cette manière, la solution sera autosuffisante et la même version de la librairie sera utilisée pour tous les projets.
Ces conseils peuvent évidemment être adaptés aux exigences de vos projets (utiliser un répertoire de librairies différent pour chaque projet et un répertoire global pour les librairies communes, mettre les assemblies à plat dans le dossier ou avoir un dossier par librairie avec des sous-dossiers par version…)
NuGet on the Block
Dans l’univers Java, Maven fait office de référence en matière de gestion de production des projets et de gestion de dépendances, de même il y a les gems dans l’écosystème Ruby. Jusqu’à pas si longtemps, il n’y avait pas d’équivalent pour .NET, des solutions existaient comme Nu, NPanday (intégration .NET pour Maven), HornGet ou OpenWrap mais elles manquaient de popularité.
Depuis octobre 2010, le monde .NET a enfin son outil de gestion de dépendances : NuGet. C’est un gestionnaire de dépendances open-source qui a pour but de simplifier le processus d’inclusion de librairies tierces dans une application .NET. NuGet n’est pas un projet de Microsoft à proprement dit mais un projet de la fondation Outercurve/Codeplex, avec des contributeurs de Microsoft et extérieurs. Le projet est géré comme un vrai projet open-source acceptant les contributions externes (une première pour Microsoft).
Avant NuGet, quand on voulait ajouter une librairie à son projet, par exemple Nunit, il fallait :
- Chercher la page du projet NUnit sur Internet.
- Chercher la page de téléchargement.
- Choisir une version à télécharger (Platforme? Version?).
- Installer ou décompresser le package.
- Copier les assemblies dans le répertoire
libde l’application. (Voir plus haut) - Ajouter les références au projet dans Visual Studio.
- Mettre à jour le fichier
web.configsi on est sur un projet d’application web. - Régler les problèmes de dépendances quand il y en a…
Grâce à NuGet, le processus se simplifie grandement :
- Cliquer sur “References > Add Library Package Reference…” dans Visual Studio 2010
- Rechercher NUnit, parmi les 800 librairies disponibles
- Cliquer sur “Install”
- Et voilà!
NuGet se charge de tout. Il télécharge les fichiers nécessaires, les place dans le répertoire « packages » à la racine de la solution et met à jour le fichier projet (il met également à jour le fichier web.config si nécessaire). Bien qu’il conserve la liste des dépendances au niveau du fichier packages.config, il ne télécharge pas automatiquement les fichiers manquants. En attendant que cette fonctionnalité soit disponible (probablement à la version 1.2), il est recommandé de mettre le dossier packages sur le gestionnaire de sources.
Pour les fous de la ligne de commande, le processus peut également se faire à l’aide de la console PowerShell et de la commande Install-Package.
NuGet est encore un projet naissant mais il semble prometteur, il simplifie grandement la gestion des dépendances et nous espérons qu’il gagnera de la popularité avec le temps, popularité nécessaire à ce type de projet.
Conclusion
Pour résumer :
- Utiliser les références entre projets pour les dépendances entre les projets d’une même solution
- Placer les librairies tierces dans un répertoire, sous contrôle du gestionnaire de source, à la racine de votre solution
- Ne pas référencer directement des librairies à partir du GAC
- Utiliser NuGet!


