Publié le 11/04/2018 Par Gaël Dupire

L’apparition du .NET Core est en train de transformer l’environnement .NET classique. Cela va certainement pousser certains projets à migrer vers ce nouveau format pour différentes raisons (en voici quelques-unes possibles ici).

Voyons ensemble dans cet article comment analyser la possibilité de porter un projet vers .NET Core et comment passer à l’acte.

Analyse des dépendances

Avant même de penser à porter son code, il faut vérifier que les dépendances utilisées ont une version compatible avec .NET Core. Pour cela, on va commencer par utiliser NuGet pour analyser les dépendances et trouver une version compatible. Ce sont les versions qui sont accompagnées du nom netstandard suivi d’un numéro de version (exemple : netstandard1.3). Certaines librairies portables sont également compatibles :

  • portable-net45-win8,
  • portable-win8-wpa8,
  • portable-net451-win81,
  • portable-net45-win8-wpa8-wpa8.

Si rien n’est disponible dans des versions compatibles, il reste plusieurs solutions :

  • contacter les développeurs (via le site de NuGet par exemple),
  • remplacer la librairie par une autre apportant des solutions équivalentes,
  • faire le portage soi-même.

Modifier le code pour assurer la compatibilité.

Même si dans l’ensemble beaucoup de lignes de code ne seront pas concernées par une migration, il faudra quand même être attentif à certains points, en commençant par passer sur des frameworks compatibles (comme ASP.NET Core par exemple). Pour du client lourd, il faudra oublier le WPF et le WinForms.

De plus, certaines parties du framework sont légèrement modifiées (comme la réflexion par exemple) et certaines ne sont tout simplement plus supportées (comme les AppDomain). On peut trouver plus d’informations ici.

Portabilité de mon projet

Il s’agit maintenant de modifier le projet en lui-même. On peut adopter deux approches. La première pour les solutions les plus petites (peu de fichiers, peu de projets) consiste à refaire une solution et recréer manuellement chacun des projets. Il faut ensuite reporter soigneusement tous les fichiers dans la nouvelle version des projets.

J’ai fait le test sur un projet F# en ligne de commande et sur un plus gros projet de test de performance en C#. La première solution est très rudimentaire puisqu’elle ne contient qu’un seul projet. Elle m’a servi à me faire la main. Pour la seconde, j’ai fait le ménage dans deux solutions de test de performance en les fusionnant. Elles utilisaient toutes les deux des librairies tierces que l’on trouve sur NuGet (NUnit, NUnitAdapter, FluentAssertion, NInject). La solution finale comprend 4 projets avec des interdépendances de projet pour au total une quarantaine de projets. Pour être honnête je n’avais jamais réalisé la fusion des solutions car c’est fastidieux comme opération. Ce test a été l’occasion d’ajouter un petit challenge supplémentaire dans le test des nouveaux outils Microsoft : toutes les opérations ont été faites en lignes de commande sur un MacBook 13 pouces. Vous trouverez les commandes NET CLI ici.

Ma conclusion personnelle ? C’est rapide et très efficace.

Pour ce faire j’ai procédé ainsi :

  • Création d’un répertoire pour la solution (disons SolutionToto)
  • On se place dans le nouveau répertoire et on utilise la commande :
    • dotnet new sln

Le nom de la solution sera directement inféré du nom du répertoire dans lequel on se trouve.

  • Création d’un répertoire pour le projet (disons ProjetToto)
  • On se place dans le nouveau répertoire et on joue la commande suivante :
    • dotnet new console -lang f#

qui aura pour effet de créer un projet console en F#.

Il y a beaucoup d’options, toutes les possibilités de Visual Studio sont accessibles en lignes de commande. Il suffit de consulter le lien donné juste au-dessus. Le nom du projet sera une nouvelle fois inféré du nom du répertoire dans lequel on se trouve.

On copie ensuite tous les fichiers du projet à migrer dans le répertoire où l’on se trouve. Ensuite on complète le fichier du projet pour que les fichiers soient pris en compte. Pour cela on édite le fichier du projet (dans mon cas un .fsproj) et on s’intéresse à la partie suivante :

  • <ItemGroup>
  •    <Compile Include="Program.fs" />
  • </ItemGroup>

Le fichier Program.fs est automatiquement créé dans le cadre du template projet Console (l’extension .fs venant du fait que le projet est en F#). Il faut maintenant ajouter une ligne

  • <Compile Include="MonFichier.fs" />

par fichier de code à ajouter pour les projets en F# car l’ordre des fichiers est important. Pour un projet C#, il n’est pas utile d’ajouter ces lignes, les fichiers contenus dans le répertoire du fichier projet sont tous vus comme appartenant à ce dernier.

Dans mon cas aucune référence n’était à ajouter, mais on trouvera dans le lien suivant d’autres détails sur les fichiers projets.

On remonte ensuite au niveau du fichier sln, et on ajoute la référence du projet à la solution en utilisant la commande :

  • dotnet sln add ./ProjetToto/ProjetToto.fsproj

On teste ensuite la compilation avec la commande suivante :

  • dotnet build SolutionToto.sln

Personnellement, ça n’a pas compilé du premier coup pour différentes raisons :

  • Dans mon processus exploratoire, j’ai édité le fichier sln et j’ai modifié l’indentation, il a fallu la rétablir. Méfiance donc dans le formatage des fichiers,
  • L’ordre des fichiers F# n’était pas le bon, c’est un problème spécifique à ce langage. Et j’ai corrigé en éditant simplement la solution et en rétablissant l’ordre.

Ce sont les seuls problèmes que j’ai rencontrés. Je ne doute pas qu’il puisse y en avoir d’autres, mais je pense que c’est très facile à réaliser et à corriger le cas échéant. D’autant que les fichiers solution/projet ont été simplifiés et sont plus faciles à lire à mon sens.

  • Si vous avez des projets qui ont besoin d’en référencer d’autres directement (sans passer par un package Nuget maison) vous pouvez utiliser la commande dotnet add reference. Si par exemple ProjetToto.fsproj a besoin du projet AwesomeLib.fsproj, il suffit de se placer dans le répertoire contenant le premier, et de lancer la commande :
  • dotnet add reference./AwesomeLib/AwesomeLib.fsproj

La seconde méthode consiste à faire le ménage manuellement dans les fichiers projet et solution. Il s’agit d’une opération qui peut être délicate en plus d’être laborieuse. On trouvera ici la plupart des points d’attention pour bien réaliser cette opération.

Les modifications se justifient pour la plupart par des simplifications et des améliorations des fichiers Projet/Solution. Il faut s’en réjouir même si cela va être la cause de beaucoup de problèmes lors des migrations.

Deux points sont aussi à prendre en compte pour une migration. D’abord, il existe un outil, l’analyseur de portabilité qui peut vous aider à étudier la faisabilité. On peut le trouver ici. Ensuite il existe une librairie de compatibilité Microsoft pour les éléments les plus difficiles à migrer. Personnellement, je l’ai utilisé pour la migration de mon projet C# et je n’ai rien noté de spécial. Vous trouverez des informations sur cette librairie ici.

Conclusion

Migrer un projet de .Net vers .Net Core s’avère plus simple que prévu. Les conseils, guides et librairies de Microsoft sur le sujet permettent d’aborder la tâche avec une certaine sérénité tandis que les points de vigilance sont clairement signalés tout au long du parcours.

Ainsi pour des solutions où le nombre de projets reste “gérable” et les librairies compatibles, une migration par création de nouveaux projets .Net Core et transfert des fichiers source apparaît comme une approche rapide et satisfaisante.

Sur des solutions de plus grande ampleur où la quantité de projets est conséquente, les interdépendances très nombreuses et les librairies très spécifiques, une approche manuelle de nettoyage, renommage et refactoring des projets sera nécessaire. Approche principalement fastidieuse et chronophage mais qui parfois pourra présenter quelques complications.

En définitive, j’ai trouvé qu’il y avait assez peu de freins concernant le “Comment” de la migration, nous permettant de nous concentrer dès le début de ce genre de réflexion sur le “Pourquoi” d’une migration vers .Net Core : librairies .Net vs .Net Core, compatibilité des Frameworks, compétences internes, supports des librairies, communauté open-source…

Restez attentifs, notre prochain article abordera justement en détails .Net Standard, .Net Framework et .Net Core pour faire le point sur la jungle .Net.

Pas encore de commentaires

Publier un commentaire

Auteur

Gaël Dupire

Gaël a débuté sa carrière en tant que Software Consultant avant de devenir Senior Software Development Engineer à la Société Générale (SGCIB) puis chez Meritis il y a 10 ans.

Gaël est diplômé de l’UTC (Doctorat de Mathématiques appliquées).

Il est passionné par les maths et leur utilisation, Il adore coder, aussi bien en .Net, python, C++ ou Matlab.