Construire un IDE .Net avec JetBrains Rider

| Chris Woodruff | Maarten Balliauw |

Le but de ce tutoriel est de vous apprendre à créer un environnement de programmation intuitif .Net avec l’ outil JetBrains Rider.

Vous pouvez le télécharger sur le site officiel de JetBrains Rider.

Un espace de discussion vous est proposé sur le forum. N’hésitez pas à apporter vos avis. Commentez

- Titre : Construire un IDE .Net avec JetBrains Rider

- Auteurs : Chris Woodruff, Maarten Balliauw

- Parution : 10 avril 2019

- Public visé :

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2019 Chris Woodruff. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Un peu d’histoire

- II. Présentation de JetBrains Rider

- III. Une couche d'interface utilisateur mince, mais intelligente

- IV. La nécessité d'un protocole personnalisé

- V. Résolution de conflit

- VI. Protocole Rider

- VII. Microservices

- VIII. Qu'en est-il de l'interface utilisateur…

- IX. Comment Rider améliore-t-il ReSharper ?

- X. Apporter plus de fonctionnalités : DataGrip, WebStorm et dotTools

- XI. Conclusion

- XII. À propos des auteurs

- XII-A. Chris Woodruff

- XII-B. Maarten Balliauw

- XIII. Remerciements Developpez.com

I - Un peu d’histoire

Avant d'entrer dans la technologie et l'architecture de Rider, voyons d'où provient cet EDI. En 2004 déjà, JetBrains envisageait de créer une application autonome pour le complément Visual Studio ReSharper. Il n'a jamais été publié, mais un prototype entièrement fonctionnel existait déjà à cette époque. Comme vous pouvez le voir sur la capture d’écran de l'interface utilisateur de ReSharper 2.0 (figure 1), il fournissait un explorateur de solutions, un éditeur, des recherches d’utilisations, des complétions de code et des refactorisations. L’interface utilisateur n’était pas particulièrement moderne, mais l’éditeur pouvait fournir des ornements pour l’affichage en ligne de la documentation, étant donné qu’elle reposait sur .NET WinForms et que Windows Presentation Foundation (WPF) n’était pas encore disponible.

Figure 1 : Interface utilisateur ReSharper 2.0

(cliquez ici pour aggrandir l'image)

Le projet a été arrêté, mais le travail n’a pas été perdu. Quelques fonctionnalités utiles pour les futures versions de ReSharper ainsi que ce qui allait devenir Rider en sont issues, notamment le système d’action, l’implémentation du contrôle de texte, plusieurs fenêtres d’outils et contrôles de barre d’outils, le lanceur de tests unitaires et les outils de ligne de commande ReSharper (CLI).

L'un des choix de conception de l'IDE ReSharper 2.0 consistait à conserver les fonctionnalités séparées de l'EDI réel. Cette approche a aidé les futures versions de ReSharper : elle pourrait prendre en charge Visual Studio 2010, 2013, 2015 et 2017, en utilisant le même noyau avec une couche d'interopérabilité IDE en haut. Cette conception s'est également révélée essentielle pour développer Rider. En gros, il suffisait de connecter une autre couche d’intégration au-dessus du cœur de ReSharper.

Comme avec l'EDI ReSharper 2.0, JetBrains souhaitait réutiliser le plus possible la technologie et les outils existants (révélation totale  : nous travaillons tous les deux pour JetBrains). Une étape logique consistait à réutiliser la plateforme EDI construite par JetBrains depuis des années : IntelliJIDEA. Il prend en charge de nombreux scénarios de développement et constitue le fondement des autres EDI de JetBrains, tels que WebStorm et IntelliJ IDEA Ultimate . Et puis il y a ReSharper ( ), qui comprend C# et VB.NET comme aucun autre EDI.

JetBrains s’est lancé dans un projet d’alliance entre IntelliJ et ReSharper. L’un fournit un front-end riche et ses outils existants, comme le contrôle de version entre autres. L'autre procure des utilitaires .NET. Chacun est construit sur une pile de technologie différente. IntelliJ est basé sur la machine virtuelle Java (JVM) et ReSharper entièrement sur .NET. Il fallait trouver un moyen pour que les deux processus puissent fonctionner ensemble.

II - Présentation de JetBrains Rider

JetBrains Rider est un EDI multiplateforme qui prend en charge .NET, Mono et .NET Core ainsi que des technologies utilisant des infrastructures telles que ASP.NET, ASP.NET Core, Xamarin et WPF. Rider prend en charge de nombreux langages, tels que C#, VB.NET, F#, JavaScript et TypeScript, pour créer des applications console, des bibliothèques, des jeux Unity, des applications mobiles Xamarin, ASP.NET MVC et d’autres types d’applications Web, telles que Angular, React et Vue.js.

Rider dispose de nombreuses fonctionnalités pour aider les développeurs .NET dans leur travail quotidien. Il prend en charge les langues prises en charge par l’achèvement du code, la génération de code, un grand nombre de références, la navigation, plus de 2.300 inspections de code, et bien plus encore. En plus de ces fonctionnalités de codage, Rider dispose également de tout ce que les développeurs .NET attendent dans leurs environnements de développement : un débogueur, un exécuteur de tests unitaires, un client NuGet (rapide !), des outils de base de données, une fenêtre de prévisualisation WPF XAML, un contrôle de version et une intégration avec des outils tels que Docker, et Unity Editor sont également présents. Même avec toutes ces fonctionnalités, Rider reste rapide, réactif et utilise beaucoup la mémoire.

III - Une couche d'interface utilisateur mince, mais intelligente

Rider utilise IntelliJ comme une fine couche sur ReSharper. IntelliJ fournit l'interface utilisateur, affichant un éditeur et un curseur de texte dans un fichier source. Certains langages, comme JavaScript et TypeScript, ont une implémentation complète du langage et Rider en bénéficie également. Pour les autres langages, tels que C#, VB.NET et F#, le front-end n'a aucune connaissance du langage lui-même : cela provient du processus d’arrière-plan de ReSharper.

Lorsque vous éditez un fichier source, IntelliJ enregistre ce que vous faites. Par exemple, lorsque vous souhaitez compléter une instruction, IntelliJ demande des éléments d’achèvement au service linguistique actuel. C#, VB.NET, F # et plusieurs autres langages n’ont pas de réelle implémentation dans le front-end de Rider, mais font plutôt appel à un service de langage de façade qui demande les informations au back-end de ReSharper. Ces informations sont ensuite renvoyées dans le serveur, où une liste des achèvements potentiels peut être affichée.

L'information circule également dans la direction inverse. Le IntelliJ de Rider dispose de l'infrastructure nécessaire pour afficher les inspections de code (« gribouillis »), mais n'a aucune notion d'inspection pour C#. Lorsqu'un fichier est ouvert, il en avertit le processus ReSharper et l'attend pour l'analyse, la réalisation d'inspections et la collecte des éléments à afficher. ReSharper publie une liste de types de documents, la sévérité de l'inspection et un texte d'info-bulle, et le front-end affiche simplement.

En fin de compte, le système IntelliJ de Rider connaît certains langages et fournit plusieurs fenêtres d’outils et des éléments comme l’intégration du contrôle de version. Pour les langages .NET, c’est vraiment une couche d’interface utilisateur mince qui fournit l’édition et une autre infrastructure, et obtient des informations du processus d’arrière-plan lorsque cela est nécessaire.

IV - La nécessité d'un protocole personnalisé

Le front-end IntelliJ de Rider comprend de nombreuses infrastructures pour l’édition, la complétion du code, l’affichage des entrées de menu, les résultats de l’inspection du code, etc. Le processus d'arrière-plan ReSharper repose sur des concepts similaires, à savoir l'achèvement du code, les inspections et la refactorisation.

En raison de ces similitudes, JetBrains a réalisé qu’il était possible de travailler avec un modèle simplifié partagé entre le front-end et un back-end. Lors de l'édition du code, nous pouvions faire circuler de petits morceaux de texte et des deltas. Recouvrer une inspection de code signifiait fournir une série de documents, une sévérité et une description. Si nous pouvons effectuer l'inspection d'un code à partir de ReSharper dans IntelliJ, nous pouvons tous les ignorer. Si nous pouvons modifier des morceaux de code dans l'éditeur et effectuer un travail de refactorisation en passant de petits morceaux de données pour mettre à jour le modèle, nous pouvons faire en sorte que tous les travaux de refactorisation fonctionnent.

JetBrains a expérimenté différentes manières de passer des actions et des petits morceaux de données entre front-end et back-end, tels que :

- Réutiliser le protocole LSP (Language Server Protocol), une idée que nous avons rejetée. LSP est génial et fait beaucoup de choses, mais c’est aussi le plus petit dénominateur commun. Certaines refactorisations dans ReSharper sont impossibles à implémenter dans LSP sans avoir recours à de nombreuses personnalisations. On ignore également comment LSP devrait gérer des langages tels que Razor, qui associe généralement C# / VB.NET et HTML, CSS et JavaScript. Il devrait y avoir un composant LSP pour les langues séparées, mais aussi un composant pour les langues combinées. LSP introduirait de nombreuses complexités et apporterait peu d'avantages pour notre cas d'utilisation particulier.

- Construire un protocole de type REST personnalisé où chaque processus pourrait appeler l'autre. JetBrains a expérimenté divers mécanismes de transport et sérialiseurs, tels que JSON et ProtoBuf. Malheureusement, ce protocole s'est avéré lent, difficile à personnaliser et sur lequel travailler pendant le développement.

Nous avons réalisé que le principal inconvénient des deux approches était qu’elles utilisaient un protocole de type appel de procédure distante (RPC). Nous aurions donc toujours à raisonner en mode « demande-action-réponse », plutôt qu’avec un flux plus naturel entre front-end et back-end qui reposent sur les mêmes concepts. Au lieu d'envoyer le message « Ajouter un fichier à la solution » au front-end et d'attendre l'accusé de réception de l'état mis à jour, nous préférerions écrire une solution.Add(nom du fichier) à un endroit et synchroniser les deux processus automatiquement, sans avoir à penser beaucoup à la résolution du conflit, ni à ce qui se passerait dans le cas d’une exception à ce moment-là.

Une autre réalisation est venue sous la forme du type de données transmises. Pour revenir aux inspections, il ne s'agirait que d'une série de documents, d'une sévérité et d'une description. Sauf dans un style RPC, nous avons besoin de plus de détails : à quelle solution s'adresse cette inspection ? Quel projet dans la solution ? Et quel fichier ? Chaque appel aurait besoin de telles informations contextuelles, ce qui rendrait les appels RPC encombrants..

Notre moment « aha » est arrivé lorsque nous avons essayé de modéliser ce protocole en tant que modèle Model-View-ViewModel (MVVM). Sa définition sur Wikipedia indique que MVVM « facilite la séparation du développement de l'interface utilisateur (vue) du développement du back-end (modèle) en utilisant un modèle de vue comme convertisseur de valeur ». IntelliJ est notre point de vue, ReSharper fournit le modèle. Et notre protocole est le modèle de vue qui partage des données légères et des données requises pour les composants de l'interface utilisateur.

Au lieu d'avoir l'état dans les deux processus et d'essayer de les maintenir synchronisés, nous avons un modèle partagé auquel les deux peuvent contribuer. En substance, exactement ce que nous voulions en premier lieu ! Lorsqu'un développeur ajoute un nouveau fichier à un projet dans le front-end, le modèle est mis à jour et les deux processus y réagissent. Lorsqu'une refactorisation en cours d'exécution dans ReSharper ajoute un nouveau fichier, ce même modèle est mis à jour et, à nouveau, les deux processus peuvent y réagir. Le modèle devient notre état et les deux parties peuvent souscrire et réagir aux modifications du modèle.

V - Résolution de conflit

MVVM en communication interprocessus ne résout pas les conflits. Les modifications peuvent provenir du serveur principal front-end ou du serveur back-end et être en conflit. Par exemple, le serveur front-end peut supprimer un fichier alors même que le serveur front-end exécute une refactorisation et génère des rapports et des mises à jour sur ce fichier supprimé dans le modèle. Lors de la saisie de code lors de l'exécution d'une refactorisation dans le back-end ReSharper, comment résoudriez-vous les modifications conflictuelles ? L’humain homme qui écrit le code gagne-t-il ? Le processus back-end qui vient de réécrire le code pour notre développeur humain est-il gagnant ? Comment gardez-vous les choses synchronisées ?

Une solution pourrait être de verrouiller et d'empêcher que de tels conflits ne se produisent. Sauf que personne ne voudrait que voir l'EDI cesser de répondre pendant la le refactoringrefactorisation. Les développeurs veulent souhaitent pouvoir supprimer ce fichier, en créer un nouveau et mettre à jour le modèle, même si une tâche plus longue n'a pas encore abouti. Nous voulons que les choses soient dynamiques vives !

JetBrains a opté pour certains concepts de base qui évitent d’avoir à résoudre empêchent la résolution des conflits :

- il y a un client et un serveur. Pour Rider, le client est IntelliJ et le serveur est ReSharper ;

- chaque valeur stockée dans le modèle de vue a une version ;

- chaque mise à jour d'une valeur par le client incrémente la version ;

- les mises à jour côté serveur n'incrémentent pas la version ;

- n'accepter les valeurs modifiées que si la version est identique ou plus récente.

Lorsqu'une valeur est modifiée par le client, le modèle de vue l'accepte. Si le serveur revient avec une modification et que le numéro de version est inférieur, cette modification n'est pas acceptée par le modèle de vue. Cela permet de s'assurer que le côté client du protocole gagne toujours en cas de conflit.

VI - Protocole Rider

JetBrains a créé et ouvert le protocole Rider avec l’approche MVVM et les règles de résolution des conflits. Mais nous ne voulions pas déranger nos développeurs avec trop de détails sur le protocole. Au lieu de cela, nous voulions que le protocole ressemble davantage à la Figure 2.

Figure 2 : Protocole Rider avec le back-end ReSharper

(cliquez ici pour aggrandir l'image)

La couche la plus basse du protocole fournit la communication elle-même et fonctionne avec des sockets. Rider utilise un protocole filaire binaire qui envoie des deltas. Il fournit le traitement par lots, si nécessaire, et prend en charge la journalisation pour vider toutes les données qui passent par le fil. Tout cela est encore trop détaillé pour fonctionner avec ce protocole au jour le jour ! Donc, JetBrains a construit un framework sur le dessus.

En faisant fonctionner les serveurs frontaux IntelliJ sur la machine virtuelle Java et ReSharper sur .NET, nous avons créé une bibliothèque Kotlin (langage JVM) et une bibliothèque C#, toutes deux prenant en charge plusieurs primitives. Nous avons également créé un générateur de code (basé sur Kotlin) qui nous permet de définir notre modèle de vue dans un langage spécifique à un domaine à l'aide de ces primitives, puis de générer un code pouvant être utilisé dans les systèmes front-end et principal.

Les équipes de développement de JetBrains avaient seulement besoin de connaître ces quelques primitives pour utiliser le protocole, au lieu de devoir apprendre toute la “magie” qui se cache derrière. Un avantage supplémentaire est que, lorsque vous utilisez ce cadre, la couche de protocole peut être générée au lieu de devoir travailler avec réflexion et introspection, ce qui contribue à la rendre performante.

Le protocole prend également en charge le concept de durée de vie, l’approche de JetBrains pour la gestion des hiérarchies d’objets. Au lieu de devoir savoir où et quand supprimer un objet de la mémoire, les objets sont attachés à une durée de vie et sont disposés lorsque la durée de vie disparaît. Par exemple, une inspection de code peut être attachée à la durée de vie d'un onglet d'éditeur. Ainsi, lorsque l'onglet d'éditeur est fermé (et que sa durée de vie prend fin), l'inspection est également supprimée de la mémoire. Et cet onglet éditeur lui-même peut être associé à la durée de vie de la solution. Ainsi, lorsque la solution se ferme (et que la durée de vie du parent prend fin), tous les objets sous-jacents sont également supprimés. IntelliJ comme ReSharper utilisent cette approche et le modèle de vue du protocole devrait y participer.

À part la durée vie, le protocole prend en charge :

- signaux : événements déclenchés lorsque quelque chose se produit ;

- propriétés : valeurs observables ;

- cartes : collections observables ;

- champs : valeurs immuables ;

- appels : appels de type RPC, nécessaires de temps en temps.

Tous ces éléments peuvent transmettre des types de données string, int, enum, classdef ou aggregatedef (un nœud du modèle de vue) et structdef (un objet contenant des données).

Cela peut sembler vague, voyons donc un exemple simplifié. Le client NuGet de Rider permet de travailler avec différentes sources de paquets. Ceux-ci ont tous un nom et une URL.

Dans le protocole, vous définissez un nœud de modèle de vue contenant les informations client NuGet (RdNuGetHost), qui possède lui-même un nœud qui gère la configuration de NuGet (configManager) et une propriété contenant les noms de source NuGet et les adresses URL (knownFeeds).

objectRdNuGetHost :
Ext(SolutionModel.Solution,
extName = "nuGetHost")
{
field("configManager",
("RdNuGetConfigManager")
{
property("knownFeeds",
immutableList(
structdef("RdNuGetFeed")
{
field("name", string)
field("url", string)
}))
})
}

Après avoir exécuté la génération de code, vous obtenez une définition de classe dans Kotlin, que le serveur IntelliJ peut utiliser, et une définition de classe en C #, que le serveur ReSharper peut utiliser, comme illustrée à la figure 3.

Figure 3 : Génération de code dans Rider

(cliquez ici pour aggrandir l'image)

Vous pouvez alors travailler contre le protocole généré. Par exemple, du côté front-end, vous pouvez définir la liste des flux dans le langage de programmation Kotlin.

configManager.knownFeeds.set(arrayListOf(
RdNuGetFeed("NuGet.org",
"https://api.nuget.org/v3/index.json")
))

Vous pouvez vous abonner à cette liste dans le code .NET back-end et réagir aux modifications. Ou vous pouvez énumérer les valeurs de la liste à un moment donné. Vous obtenez même la complétion de code, grâce à la génération du code de protocole, comme illustrée dans la figure 4.

Figure 4 : exemple de complétion de code dans Rider

(cliquez ici pour aggrandir l'image)

En substance, grâce à la génération de code pour le protocole, vous pouvez travailler sur le même modèle sans vous soucier de la communication et de la maintenance des états entre les serveurs front-end IntelliJ et ReSharper.

VII - Microservices

Nous avons déjà évoqué le fait que Rider est constitué de deux processus : le front-end IntelliJ et le back-end ReSharper. Étant donné que les deux systèmes s'exécutent sur une stack technologique différente (JVM ou .NET), Rider doit exécuter plusieurs processus qui communiquent entre eux via le protocole Rider. L’exécution de plusieurs processus présente quelques avantages : chacun dispose de son propre espace mémoire 64 bits et, sur les machines multicœurs, il est probable que ces processus s’exécutent sur leurs propres cœurs de processeur, ce qui leur permet de meilleures performances.

Il y a un autre avantage tout aussi intéressant : l'isolement. Plusieurs processus s'exécutent indépendamment les uns des autres (hormis la communication via le protocole), afin de pouvoir exécuter le « ramassage des déchets » indépendamment, ainsi que de démarrer et d'arrêter indépendamment. Imaginez que vous puissiez démarrer et arrêter des processus en fonction de vos besoins, avec leur propre espace mémoire, leur propre collecteur de mémoire, et éventuellement sur leur propre microprocesseur ?

Rider peut exécuter plus de deux processus, en fonction du type de solution avec laquelle vous travaillez. Lorsque vous travaillez sur un projet Windows Presentation Foundation (WPF), trois processus peuvent s'exécuter, comme illustrée à la figure 5 :

Figure 5 : aperçu de WPAM XAML dans Rider

(cliquez ici pour aggrandir l'image)

L’éditeur lui-même est l’interface front-end IntelliJ de Rider, et l’achèvement du code, l’analyse du code, les corrections rapides, etc., sont optimisés par le back-end ReSharper de Rider. La fenêtre d'aperçu XAML en bas est un troisième processus : le front-end de ReSharper détecte que vous travaillez sur une application WPF et active un processus de rendu qui communique une représentation bitmap avec ReSharper via une autre instance du protocole (Figure 6).

Figure 6 : Processus du pilote avec le rendu de prévisualisation XAML

(cliquez ici pour aggrandir l'image)

Rider prend également en charge l’exécution des analyseurs Roslyn. De nombreuses équipes de développement écrivent leurs propres analyseurs afin de fournir un outil supplémentaire pour les frameworks qu'elles construisent. Dans Rider, le serveur ReSharper lance un processus séparé analysant le code à l'aide de Roslyn, puis communique les résultats au serveur IntelliJ (Figure 7 ).

Figure 7 : Processus du coureur avec Roslyn

(cliquez ici pour aggrandir l'image)

Le débogueur s'exécute également dans un processus séparé, créé par le front-end ReSharper et communiquant à l'aide du protocole Rider. Ainsi, lorsque vous ouvrez la fenêtre de l'outil « Aperçu XAML » dans un projet utilisant des analyseurs Roslyn et que vous le déboguez, les processus en cours d'exécution seront encore plus nombreux (Figure 8).

Figure 8 : Processus du pilote avec le débogueur

(cliquez ici pour aggrandir l'image)

Avec une architecture où vous pouvez démarrer et arrêter des processus à la demande, vous pouvez réaliser un certain nombre de choses :

- séparer l’espace mémoire et la récupération de place indépendante ;

- démarrer/arrêter la fonctionnalité à la demande, en ne chargeant que la totalité des fonctionnalités lorsque la solution l'exige ;

- crashes indépendants. Cela devient important dans des processus tels que le rendu XAML Preview, dans lequel vous devrez peut-être restituer des données utilisateur erronées. Dans ces cas, vous pouvez échouer normalement et simplement arrêter un processus au lieu de l'EDI entier.

Il y a un avantage supplémentaire dont nous n'avons pas encore parlé. Comme le protocole Rider est basé sur le socket, les processus ne doivent pas nécessairement s'exécuter sur le même ordinateur. Par exemple, dans la prise en charge du débogage Docker, le processus de débogage s’exécute dans un conteneur Docker (essentiellement un ordinateur différent) et communique avec le processus d’arrière-plan ReSharper de Rider. Cela ouvre la porte à de nombreuses possibilités, maintenant et à l'avenir.

Dans presque tous les exemples que nous avons examinés jusqu’à présent, Rider est responsable du processus qui est démarré/arrêté. Pour l’intégration avec l’éditeur Unity, Rider n’est pas propriétaire du processus. Rider et Unity Editor peuvent être lancés indépendamment, mais cela n’empêche pas les deux processus de rechercher la connexion entre leurs protocoles respectifs. Lorsque les deux sont lancés et que la connexion est autorisée, Rider peut partager son modèle de vue avec Unity Editor et inversement. Cela permet à Rider de contrôler les boutons de lecture, de pause et d’arrêt dans Unity, et offre également la possibilité de déboguer du code dans Rider, même s’il est exécuté dans l’éditeur Unity (Figure 9) !

Figure 9 : Le débogage d’unité de Rider en action sous Mac OS X

(cliquez ici pour aggrandir l'image)

Si vous êtes intéressé par les composants internes de ce plug-in, il est disponible en open-source (https://github.com/JetBrains/resharper-unity) afin que vous puissiez consulter son front-end IntelliJ, son back-end ReSharper, et le plug-in Unity Editor. Microservices !

VIII - Qu'en est-il de l'interface utilisateur…

Jusqu’à présent, nous nous sommes concentrés sur le partage du modèle de vue entre le front-end IntelliJ de Rider et le back-end ReSharper. Qu'en est-il de la vue elle-même ? Certes, Rider doit également disposer d’un certain nombre d’éléments d’interface utilisateur et de fenêtres d’outils dans la vue.

C’est tout à fait correct. Les inspections de code de surface et les solutions rapides partagent en réalité une série de documents, une sévérité et une description, et ne nécessitent aucune modification du front-end, car ils réutilisent ce qui est déjà dans IntelliJ. À d’autres endroits, par exemple dans la fenêtre de l’outil NuGet, vous devez implémenter chaque fonctionnalité en plus du protocole que vous avez créé.

En développant des versions plus récentes de Rider, JetBrains a pris conscience que de nombreuses interfaces utilisateur et éléments d’interface utilisateur sont de nature similaire. Par exemple, tous les paramètres d'inspection sont approximativement une liste d'inspections, leur sévérité et un booléen qui les active ou les désactive. Les paramètres de ceux-ci partagent tous le même contrôle utilisateur qui lie cette liste à une vue de grille.

Pour de nombreux autres paramètres, l'interface utilisateur est souvent un en-tête, suivi d'un ou plusieurs morceaux de texte, suivi d'une case à cocher, d'une zone de texte ou d'une liste déroulante. Au lieu de les reconstruire tout le temps, nous avons commencé à créer des vues standard que vous pouvez remplir à l'aide du protocole. Par exemple, les paramètres C# Interactive dans Rider sont définis dans le back-end ReSharper, à l'aide de l'extrait de code suivant :

AddHeader("Tool settings");
AddToolPathFileChooserOption(lifetime,
commonFileDialogs);
AddEmptyLine();
AddStringOption(
(CSharpInteractiveOptions s)
=>s.ToolArguments,
"Tool arguments:")
AddHeader("Tool window behavior");
AddBoolOption(
(CSharpInteractiveOptions s)
=>s.FocusOnOpenToolWindow,
"Focus tool window on open");
AddBoolOption(
(CSharpInteractiveOptions s)
=>s.FocusOnSendLineText,
"Focus tool window on Send Line");
AddBoolOption(
(CSharpInteractiveOptions s)
=>s.MoveCaretOnSendLineText,
"Move caret down on Send Line");

Le front-end peut ensuite les restituer, et dans le navigateur IntelliJ de Rider, vous verrez un volet de paramètres approprié (Figure 10) :

Figure 10 : Volet Paramètres du Rider

(cliquez ici pour aggrandir l'image)

IX - Comment Rider améliore-t-il ReSharper ?

Nous avons évoqué le fait que Rider réutilisait autant que possible ReSharper. L'avantage de cela est que les fonctionnalités ajoutées par JetBrains à Rider sont également disponibles dans ReSharper et les fonctionnalités ajoutées par JetBrains au flux ReSharper dans Rider.

Cela signifie également que les optimisations de performances vont de l'une à l'autre. Si JetBrains optimise la vitesse de chargement de la solution dans ReSharper, Rider en tirera parti. Si JetBrains optimise le chargement des composants IDE dans Rider, ReSharper en profitera également.

Pour Rider, JetBrains s’emploie à faire en sorte que le back-end ReSharper s’exécute sur le .NET Core CLR au lieu d’exiger l’intégralité du .NET Framework (sous Windows) ou Mono (sous Mac OS X et Linux). Cet effort profitera à Rider dans la mesure où l’environnement d’exécution de toutes les plateformes sera le .NET Core, au lieu d’avoir deux environnements d’exécution actuels. Rider bénéficiera également des nombreuses améliorations de performances apportées dans .NET Core, tout comme ReSharper.

Le fait que Rider exécute ReSharper en tant que processus séparé ouvre également la porte à l'exécution de Visual Studio avec ReSharper en tant que processus séparé. JetBrains y travaille activement et cela apportera les avantages décrits dans cet article : Visual Studio et ReSharper s'exécuteront dans leurs propres processus isolés et disposeront de leur propre espace mémoire et, éventuellement, de leurs propres cœurs de processeur. Avec les modifications apportées à la prise en charge de l'exécution de ReSharper sur le .NET Core CLR, cela améliorera considérablement les performances de ReSharper dans Visual Studio !

X - Apporter plus de fonctionnalités : DataGrip, WebStorm et dotTools

Le principal point fort de Rider, force de l’EDI, provient de la disponibilité des fonctionnalités des autres EDI de la famille IntelliJ. Pour les développeurs .NET et ASP.NET, JetBrains a intégré de nombreuses fonctionnalités des IDE DataGrip et WebStorm dans Rider, essentiellement en regroupant des plug-ins existants avec Rider.

En regroupant les outils de base de données de DataGrip, Rider offre une expérience enrichie pour l'utilisation de données et de bases de données, prenant en charge Oracle, MySQL, Microsoft SQL Server, la base de données Azure SQL, etc. Les utilisateurs Rider peuvent écrire du code SQL en utilisant l'intelligence de l'éditeur de texte SQL, exécuter des instructions SQL, afficher des ensembles de résultats et naviguer rapidement dans le schéma de base de données pour consulter les tables, les vues et les procédures de la base de données utilisée.

JetBrains souhaite aller au-delà du simple regroupement de plug-ins et de fonctionnalités existants. Parce que nous estimons que 1+2=3, nous cherchons activement à étendre les fonctionnalités. Et ce serait bien si nous pouvions fournir l'achèvement la complétion du code SQL à l'intérieur d'une chaîne dans un fichier C# ? Ou fournir fournissez une action Alt + Entrée pour exécuter cette requête ? C’est exactement ce sur quoi nous travaillons. Comme nous bénéficions de l'intelligence des deux processus (et peut-être d'autres microservices contribuant), l'EDI peut devenir encore plus intelligent.

D'autres exemples avec sont dans la disponibilité des fonctionnalités de WebStorm fournies. Avec l'essor du développement basé sur le client Web au cours de la dernière décennie, la plupart des développeurs ASP.NET et ASP.NET Core ont compris la nécessité de renforcer leur utilisation de JavaScript dans leurs projets et solutions. Rider fonctionne et comprend non seulement le code JavaScript dans l'éditeur, mais également les frameworks Web les plus populaires, notamment Angular, React et Vue.js. Rider fonctionne et comprend non seulement le code JavaScript dans l'éditeur, mais également les frameworks Web les plus populaires, notamment Angular, React et Vue.js. Rider vous permet de vérifier votre code Web en utilisant ses propres fonctionnalités d'analyse de code, combinées aux linters open source les plus populaires disponibles à ce jour. Vous pouvez également déboguer et tester tout votre code JavaScript indépendamment de votre code .NET à l'aide des débogueurs intégrés et de la fonctionnalité de test unitaire de WebStorm. Il existe même un client REST pour tester vos API Web construites avec ASP.NET et ASP.NET Core.

À l'heure actuelle, lorsque vous travaillez dans un fichier TypeScript, toutes les fonctionnalités connexes sont fournies par le plug-in WebStorm sur le front-end. Cependant, ReSharper possède également de nombreuses fonctionnalités liées à JavaScript, TypeScript, HTML, etc. Nous travaillons actuellement pour combiner le meilleur des deux mondes en intégrant à la fois le front-end et le back-end, l’analyse de code, la complétion, la génération de code, etc.

Dans Rider 2018.2, la couverture de code et les tests en continu sont intégrés. Ceci est alimenté par un autre processus back-end : dotCover. Des fonctionnalités supplémentaires viendront de dotTrace (profileur de performances de JetBrains) et de dotMemory (profileur de mémoire de JetBrains). Pour l'instant, ceux-ci ne fonctionnent que sous Windows. L’objectif est d’exécuter ces outils sur Mac OS X et Linux, apportant également des fonctionnalités de profilage riches dans Rider sur ces plateformes.

XI - Conclusion

L’avenir du développement .NET et ASP.NET est très prometteur et excitant. Et avec Rider nous voulons y contribuer. JetBrains prévoit d’ajouter et d’améliorer la prise en charge de nombreuses technologies utilisées actuellement par les développeurs .NET, telles que Azure, WinForms, WPF, Xamarin et .NET Core. JetBrains s'emploie également à améliorer les performances de Rider en améliorant le temps de démarrage lors de l'ouverture de solutions .NET ainsi qu'en ajoutant un typage sans latence dans les éditeurs.

Les autres évolutions à venir incluent la possibilité de travailler avec du code C++ au sein de solutions et de projets, et d'ouvrir l'écosystème de plug-ins en fournissant un SDK plus simple qui permette aux développeurs de plug-ins d'étendre le front-end IntelliJ de Rider, son back-end ReSharper ou les deux.

Nous espérons que cet article vous fournira quelques informations sur l'EDI Rider, ainsi que sur le défi à relever auquel est confrontée la combinaison pour combiner des produits existants fonctionnant sur différentes piles de technologies. Rider est un EDI .NET très riche et enrichissant que vous pouvez utiliser sous Windows, Mac OS X et Linux. Testez-le vous-même. Une version d’essai gratuite est disponible à l’adresse : https://www.jetbrains.com/rider.

XII - À propos des auteurs

XII-A - Chris Woodruff

Chris Woodruff (plus connu sous le nom de Woody) est diplômé en informatique du College of Engineering de la Michigan State University. Woody développe et conçoit des solutions logicielles depuis plus de 20 ans et a travaillé sur de nombreuses plateformes et outils. C’est un leader de la communauté qui a notamment participé aux événements GRDevNight, GRDevDay, West Michigan Day of .NET et Beer City Code. Il a également joué un rôle déterminant dans l'organisation du célèbre événement Give Camp dans l'Oouest du Michigan, où des professionnels de la technologie mettent leur temps et leur expertise en développement au service des organisations à but non lucratif locales. En tant que conférencier et podcasteur, Woody a abordé divers sujets, notamment la conception de bases de données et l'open source. Il a été un MVP Microsoft dans Visual C#, Data Platform et SQL, et a été reconnu en 2010 comme l’un des 20 meilleurs MVP du monde. Woody est Developer Advocate pour un défenseur des intérêts de JetBrains et représente JetBrains et évangélise les produits .NET, .NET Core et JetBrains en Amérique du Nord.

XII-B - Maarten Balliauw

Maarten Balliauw aime créer des applications Web et cloud. Ses principaux centres d’intérêt sont les technologies Web .NET, C #, Microsoft Azure et les performances des applications. Il est Developer Advocate chez JetBrains, ASP Insider et ancien MVP de Microsoft. Maarten intervient fréquemment lors d’événements nationaux et internationaux et organise des événements pour les groupes d'utilisateurs Azure en Belgique. Pendant son temps libre, il brasse sa propre bière.

XIII - Remerciements Developpez.com

Developpez.com remercie Chris Woodruff et Maarten Balliauw pour l’autorisation de publication de ce tutoriel, initialement publié dans CODE Magazine. Tous les remerciements aussi à Guillaume SIGUI pour la mise au gabarit et f-leb pour la relecture orthographique.

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article

Retour à l'article