ILMerge: une solution aux problèmes liés aux dépendances

Auteur du billet de blog : Rudy Spano - Neotech Solutions

Rudy Spano

Consultant .Net
  Publié le mardi 4 octobre 2016

Expert technique .Net passionné par tout ce qui est innovant en environnement Microsoft. De la mobilité, du client lourd (Xaml Applications) mais aussi une petite pointe de Web...

Introduction

Lorsque l’on débute le développement .Net, la gestion des dll externes semble un sujet trivial…  Il suffit de récupérer une dll .NET sur internet, la référencer et faire appel au code de celle-ci ou encore mieux utiliser Nuget !

Puis au fur et à mesure des expériences, on découvre des problématiques qui n’ont pas fini de faire suer les développeurs…

Dans ce billet, je vous décriverai les situations qui posent souvent problème et je vous présenterai la solution ILMerge peu connue mais qui peut s’avérer très efficace !

 

Problématique : dll manquante

Considérons la situation suivante :

 

Basiquement, (sans parler du GAC notamment), la compilation de notre exécutable Application.exe va constituer notre dossier bin : répertoire de l’exécutable généré, avec :

  • L’exécutable lui-même
  • Les dll « externes » référencées par l’exécutable
  • Les dll des différentes couches elles-mêmes compilées
  • Pour chacune de ces couches :
    • Les références utilisées explicitement via du code

C’est ce dernier point qui pose problème :(… En effet, il arrive que l’une de nos class library/dll dépende d’une dll sans pour autant l’utiliser directement (chargement dynamique, dll non managée, …).

 

Problématique : conflits de version

Soit la situation suivante :

 

On utilise deux libraries qui font référence à la même dll mais dans une version différente. Dans le dossier bin, il n’y aura qu’une seule dll. La version présente et utilisée par l’une des libraries ne sera donc pas celle attendue. En résulte :

  • Des résultats inattendus car la library n’a pas été validée avec cette version.
  • Des exceptions de type MissingMethodException par exemple si on tombe sur un breaking change.
  • ...

Cette problématique est assez fréquente avec les dépendances à des libraries utilitaires d’entreprise ou avec des libraries très populaires type NewtonSoft.Json.

En tant que fournisseur de library, vous pouvez tenter de vous assurer que la dépendance dont vous avez besoin est dans la version adéquate via divers mécanismes :

Toutefois, en faisant cela, vous mettrez des bâtons dans les roues des développeurs qui seront bloqués à cette version de dépendance. Ce qui risque notamment de rendre votre library incompatible avec d’autres libraries ou leur imposer d’utiliser des mécanismes tels que les bindingRedirect.

 

Un compromis intéressant : ILMerge

Afin de répondre, entre autres, aux 2 problématiques précédentes, vous pouvez utiliser ILMerge.

Cet outil en ligne de commande vous permet d’embarquer le code de vos dépendances directement dans la dll de votre library. Utiliser cet outil offre de multiples avantages :

  • Vous pouvez ajouter n’importe quelle dépendance pour ne pas réinventer la roue.
  • Vous êtes sûr du code de la dépendance utilisé.
  • Vous livrez une dll auto-suffisante. Voir un exécutable auto-suffisant !
  • Vous n’affichez pas vos dépendances (sécurité).
  • Vous permettez à l’application intégrant votre library d’utiliser une autre version de la dépendance.

 

Exemple de commande :

ilmerge /out:Merged.dll Primary.dll SecondaryOne.dll SecondaryTwo.dll /internalize

 

NB : le paramètre /internalize vous permet de passer tout le code de la dépendance en Internal, ce qui évitera les conflits de Namespace si une autre version de la dépendance est utilisée ailleurs.

Vous pouvez alors exécuter cette commande en Post-Build event

 

Je vous conseille sinon fortement une alternative : l’utilisation du paquet nuget MSBuild ILMerge task qui vous permettra de lancer les commandes ILMerge en toute simplicité sur le projet souhaité !

 

Alors, convaincus ?

Commentaires