Définir un langage spécifique à un domaine
Pour définir un langage spécifique à un domaine (DSL, Domain-Specific Language), vous devez créer une solution Visual Studio à partir d'un modèle. Le composant principal de la solution est le diagramme de définition DSL, qui est stocké dans DslDefinition.dsl. La définition DSL définit les classes et les formes de la solution DSL. Après avoir modifié et ajouté à ces éléments, vous pouvez ajouter du code programme pour personnaliser la solution DSL plus en détail.
Si vous débutez avec les DSL, nous vous recommandons de travailler via le laboratoire d’outils DSL, que vous trouverez sur ce site : Kit de développement logiciel (SDK) Visualization and Modeling
Sélection d'une solution de modèle
Pour définir un DSL, vous devez avoir installé les composants suivants :
- Visual Studio
- Charge de travail de développement d’extension Visual Studio (inclut le Kit de développement logiciel (SDK) Visual Studio)
- Kit de développement logiciel (SDK) de modélisation (installez-le en tant que composant individuel dans Visual Studio)
Notes
Le composant Transformation de modèle de texte est automatiquement installé dans le cadre de la charge de travail Développement d’extensions Visual Studio. Vous pouvez aussi l’installer à partir de l’onglet Composants individuels de Visual Studio Installer, sous la catégorie SDK, bibliothèques et frameworks. Installez le composant Modeling SDK à partir de l’onglet Composants individuels.
Pour créer un langage spécifique à un domaine, vous devez créer une solution Visual Studio à l'aide du modèle de projet Langage spécifique à un domaine.
Pour créer une solution DSL
Créez un projet Langage spécifique à un domaine.
L’Assistant langage spécifique à un domaine s’ouvre et affiche une liste de modèles de solutions DSL.
Cliquez sur chaque modèle pour afficher une description. Choisissez la solution qui ressemble le plus à ce que vous voulez créer.
Chaque modèle DSL définit une solution DSL de base opérationnelle. Vous modifierez cette solution DSL en fonction de vos exigences.
Cliquez sur chaque exemple pour obtenir plus d'informations.
Sélectionnez Flux de tâches pour créer une solution DSL avec des couloirs. Les couloirs sont des partitions verticales ou horizontales du diagramme.
Sélectionnez Modèles de composants pour créer une solution DSL avec des ports. Les ports sont de petites formes sur le bord d'une forme plus grande.
Sélectionnez Diagrammes de classes pour définir une solution DSL avec des formes de compartiments. Les formes de compartiments contiennent des listes d'éléments.
Sélectionnez Langage minimal dans les autres cas ou si vous avez des doutes.
Sélectionnez Concepteur WinForm minimal ou Concepteur WPF minimal pour créer une solution DSL affichée sur un Windows Forms ou une aire WPF. Vous devrez écrire du code pour définir l'éditeur. Pour plus d'informations, voir les rubriques suivantes :
Création d'un langage spécifique à un domaine basé sur Windows Forms
Entrez une extension de nom de fichier pour votre solution DSL dans la page appropriée de l'Assistant. Il s'agit de l'extension qui sera utilisée par les fichiers contenant des instances de votre solution DSL.
Choisissez une extension de nom de fichier qui n'est associée à aucune application sur votre ordinateur ou sur l'ordinateur où vous voulez installer la solution DSL. Par exemple, docx et htm seraient des extensions de nom de fichier inacceptables.
L'Assistant vous avertit si l'extension que vous avez entrée est utilisée actuellement comme DSL. Dans ce cas, utilisez une autre extension de nom de fichier. Vous pouvez aussi réinitialiser l'instance expérimentale du Kit SDK Visual Studio pour effacer les anciennes conceptions expérimentales. Dans le menu Démarrer de Windows, tapez réinitialiser le Visual Studio, puis exécutez Réinitialiser la commande Microsoft Visual Studio Experimental Instance correspondant à votre version de Visual Studio.
Vous pouvez ajuster les paramètres sur les autres pages ou conserver les valeurs par défaut.
Cliquez sur Terminer.
L'Assistant crée une solution qui contient deux ou trois projets et il génère du code à partir de la définition DSL.
L'interface utilisateur ressemble maintenant à l'image suivante.
Cette solution définit un langage spécifique à un domaine. Pour plus d’informations, consultez Vue d’ensemble de l’interface utilisateur des outils de langage spécifiques à un domaine.
Tester la solution
Le modèle de solution fournit une solution DSL opérationnelle, que vous pouvez modifier ou utiliser telle quelle.
Pour tester la solution, appuyez sur F5 ou Ctrl+F5. Une nouvelle instance de Visual Studio s'ouvre en mode expérimental.
Dans la nouvelle instance de Visual Studio, dans l'Explorateur de solutions, ouvrez l'exemple de fichier. Il s'ouvre sous forme de diagramme, avec une boîte à outils.
Si vous exécutez une solution que vous avez créée à partir du modèle Langage minimal, votre instance expérimentale de Visual Studio ressemblera à l'exemple suivant :
Expérimentez avec les outils. Créez des éléments et raccordez-les.
Fermez l’instance expérimentale de Visual Studio.
Notes
Une fois la solution DSL modifiée, vous ne pourrez plus voir les formes dans l'exemple de fichier test. En revanche, vous pourrez créer des éléments.
Modification du modèle de solution DSL
Renommez et conservez tout ou une partie des classes de domaine et des classes de forme dans le modèle de définition DSL. Vos nouveaux noms de classes doivent être des noms CLR valides, sans espace ni ponctuation.
Il est particulièrement utile de conserver les classes suivantes :
La classe racine apparaît en haut à gauche du diagramme de définition DSL, sous Classes et relations. Affectez-lui un nom différent de la solution DSL. Par exemple, une solution DSL nommée BibliothèqueMusicale peut avoir une classe racine nommée Musique.
La classe de diagramme apparaît en bas à droite du diagramme de définition DSL, dans la colonne Éléments du diagramme. Vous devrez peut-être faire défiler la page vers la droite pour la voir. Elle se nomme en général Votre_Solution_DSLDiagramme.
Si vous avez utilisé le modèle Flux de tâches et que vous voulez créer des diagrammes avec des couloirs, conservez et renommez la classe de domaine Actor et la forme ActorSwimlane.
Supprimez ou renommez d'autres classes en fonction de vos exigences.
Modèles pour définir une solution DSL
Nous vous recommandons de développer une solution DSL en ajoutant ou en ajustant une ou deux fonctionnalités à la fois. Ajoutez une fonctionnalité, exécutez la solution DSL et testez-la, puis ajoutez une ou deux fonctionnalités supplémentaires. Une solution DSL ordinaire peut être constituée des éléments suivants :
Une classe de domaine, la relation d'incorporation qui connecte l'élément au modèle, la forme requise pour afficher les éléments de cette classe sur le diagramme et l'outil d'élément qui permet aux utilisateurs de créer des éléments.
Les propriétés de domaine d'une classe de domaine et les décorateurs qui les affichent sur une forme.
Une relation de référence et le connecteur qui l'affiche sur le diagramme, ainsi que l'outil de connecteur qui permet aux utilisateurs de créer des liens.
Une personnalisation qui nécessite du code de programme, telle qu'une contrainte de validation ou une commande de menu.
Les sections suivantes expliquent comment construire les types de fonctionnalités DSL les plus utiles. Il existe de nombreux autres modèles avec lesquels vous pouvez construire une solution DSL, mais les modèles suivants sont les plus couramment utilisés.
Notes
Après avoir ajouté une fonctionnalité, n'oubliez pas de cliquer sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions avant de générer et d'exécuter votre solution DSL.
La figure suivante montre la partie classes et relations de la solution DSL qui est utilisée comme exemple dans cette rubrique.
La figure suivante est un exemple de modèle de cette solution DSL :
Notes
Le terme « modèle » fait référence à une instance de votre solution DSL créée par les utilisateurs. Elle est généralement affichée sous forme de diagramme. Cette rubrique traite du diagramme de définition DSL et des diagrammes de modèles qui apparaissent lors de l'utilisation de votre solution DSL.
Définition des classes de domaine
Les classes de domaine représentent les concepts de votre solution DSL. Les instances sont des éléments de modèle. Par exemple, dans une solution DSL BibliothèqueMusicale, vous pourriez avoir des classes de domaine nommées Album et Morceau.
Pour créer une classe de domaine, vous pouvez faire glisser un élément à partir de l'outil Classe de domaine nommée vers le diagramme, puis renommer la classe.
Pour plus d’informations, consultez Propriétés des classes de domaine.
Créer une relation d'incorporation pour chaque classe de domaine
Chaque classe de domaine, à l'exception de la classe racine, doit être la cible d'au moins une relation d'incorporation ou elle doit hériter d'une classe qui est la cible d'une relation d'incorporation.
Dans un modèle, chaque élément de modèle est un nœud dans une arborescence unique de relations d'incorporation. On utilise souvent les termes « parent » et « enfant » pour faire référence à la source et à la cible d'une relation d'incorporation.
La sélection d'un parent pour une classe de domaine dépend de la façon dont vous souhaitez que la durée de vie de ses éléments dépende d'autres éléments. Si un nœud d'une arborescence est supprimé, sa sous-arborescence est généralement supprimée également. Les classes d'éléments qui ont une existence indépendante sont par conséquent incorporées directement sous la classe racine.
En général, si vous affichez un élément dans un autre, vous devez indiquer une relation de propriété. Dans ce cas, la classe parente la plus appropriée est la classe du conteneur. Il y a toutefois une exception : quand l'élément que vous voyez dans un conteneur n'est en réalité qu'un lien de référence à un élément indépendant. Dans ce cas, le fait de supprimer le conteneur supprime la référence mais pas sa cible.
Dans les modèles de définition DSL décrits dans cette rubrique, nous partons du principe que les éléments affichés dans un conteneur seront supprimés lors de la suppression du conteneur. Des schémas plus complexes sont possibles et peuvent être obtenus en définissant des règles.
Mode d'affichage de l'élément | Classe parente (incorporation) | Exemple dans le modèle de solution DSL |
---|---|---|
Forme sur le diagramme. Couloir. |
Classe racine de solution DSL. | Langage minimal. Flux de tâches : classe Actor. |
Forme dans un couloir. | Classe de domaine d'éléments qui sont affichés sous forme de couloirs. | Flux de tâches : classe Task. |
Élément dans une liste dans une forme, où l'élément est supprimé si le conteneur est supprimé. Port sur le bord d'une forme. |
Classe de domaine mappée à la forme de conteneur. | Diagramme de classes : classe Attribute. Diagramme de composants : classe Port. |
Élément dans une liste, non supprimé en cas de suppression du conteneur. | Classe racine de solution DSL. La liste affiche des liens de référence. |
|
Non affiché directement. | Classe dont il fait partie. |
Dans l'exemple de bibliothèque musicale, les albums sont affichés sous forme de rectangles dans lesquels les titres des morceaux sont énumérés. Ainsi, le parent d'Album est la classe racine Music et le parent de Song est Album.
Pour créer une classe de domaine et son incorporation en même temps, cliquez sur l'outil Relation d'incorporation, cliquez sur la classe parente, puis sur une partie vierge du diagramme.
Il n'est généralement pas nécessaire d'ajuster le nom de la relation d'incorporation et de ses rôles, car ils effectueront le suivi des noms de classes automatiquement.
Pour plus d’informations, consultez Propriétés des relations de domaine et Propriétés des rôles de domaine.
Notes
L'incorporation n'est pas la même chose que l'héritage. Les enfants dans une relation d'incorporation n'héritent pas des fonctionnalités de leurs parents.
Ajouter des propriétés de domaine à chaque classe de domaine
Les propriétés de domaine contiennent des valeurs. En voici quelques exemples : Nom, Titre, Date de publication.
Cliquez sur Propriétés de domaine dans la classe, appuyez sur la touche Entrée, puis tapez le nom d'une propriété. Le type par défaut d'une propriété de domaine est String. Si vous voulez modifier le type, sélectionnez la propriété de domaine et définissez le Type dans la fenêtre Propriétés. Si le type souhaité ne figure pas dans la liste déroulante, consultez Ajout de types de propriétés.
Définissez une propriété de nom d'élément. Sélectionnez une propriété de domaine qui peut servir à identifier des éléments dans l'explorateur de langage. Par exemple, dans la classe de domaine Morceau, vous pourriez sélectionner la propriété de domaine Titre. Dans la fenêtre Propriétés, affectez la valeur true
à la propriété Is Element Name.
Créer des classes de domaine dérivées
Si vous souhaitez qu'une classe de domaine ait des variantes qui héritent de ses propriétés et relations, créez des classes qui en dérivent. Par exemple, Album peut avoir des classes dérivées WMA et MP3.
Créez la classe dérivée à l'aide de l'outil Classe de domaine.
Cliquez sur l'outil Héritage, sur la classe dérivée, puis sur la classe de base.
Vous pouvez affecter la valeur abstract au Modificateur d'héritage de la classe de base. Si vous pensez que vous pourriez avoir besoin d'instances de la classe de base, créez plutôt une classe dérivée distincte pour elles.
Les classes dérivées héritent des propriétés et des rôles de leurs classes de base.
Mettre en ordre le diagramme de définition DSL
Quand vous ajoutez des relations, certaines de vos classes apparaissent à plusieurs emplacements. Pour réduire le nombre d'apparences et élargir le diagramme, cliquez avec le bouton droit sur la classe cible d'une relation, puis cliquez sur Déplacer l'arborescence à cet endroit. Pour l'effet opposé, cliquez avec le bouton droit sur la classe cible d'une relation et cliquez sur Fractionner l'arborescence. Si ces commandes de menu ne sont pas visibles, assurez-vous que seule la classe de domaine est sélectionnée.
Utilisez Ctrl+Haut et Ctrl+Bas pour déplacer des classes de domaine et des classes de forme.
Tester les classes de domaine
Pour tester les nouvelles classes de domaine
Cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions pour générer le code du concepteur DSL. Vous pouvez automatiser cette étape. Pour plus d’informations, consultez Comment automatiser la transformation de tous les modèles.
Générez et exécutez la solution DSL. Appuyez sur F5 ou Ctrl+F5 pour exécuter une nouvelle instance de Visual Studio en mode expérimental. Dans l'instance expérimentale de Visual Studio, ouvrez ou créez un fichier ayant l'extension de nom de fichier de votre solution DSL.
Ouvrez l'explorateur. Sur le côté du diagramme se trouve la fenêtre de l'explorateur de langage, qui se nomme généralement Explorateur Votre_Langage. Si cette fenêtre n'est pas visible, elle est peut-être sous un onglet sous l'Explorateur de solutions. Si vous ne la trouvez pas, dans le menu Affichage, pointez sur Autres fenêtres, puis cliquez sur Explorateur Votre_Langage.
Votre explorateur présente une arborescence du modèle.
Créez des éléments. Cliquez avec le bouton droit sur le nœud racine, puis cliquez sur Ajouter nouveauVotre_Classe.
Une nouvelle instance de votre classe apparaît dans votre explorateur de langage.
Vérifiez que chaque instance possède un nom différent quand vous créez des instances. Cela sera le cas uniquement si vous avez défini l'indicateur Is Element Name sur une propriété de domaine.
Examinez les propriétés de domaine. Après avoir sélectionné une instance de votre classe, examinez la fenêtre Propriétés. Elle doit contenir les propriétés de domaine que vous avez définies sur cette classe de domaine.
Enregistrez le fichier, fermez-le, puis rouvrez-le. Toutes les instances que vous avez créées doivent être visibles dans l'explorateur, une fois que vous avez développé les nœuds.
Définition de formes sur le diagramme
Vous pouvez définir des classes d'éléments qui apparaissent sur un diagramme sous forme de rectangles, d'ellipses ou d'icônes.
Pour définir une classe d'éléments qui apparaissent en tant que formes sur un diagramme
Définissez et testez une classe de domaine comme décrit dans Définition des classes de domaine .
Le parent de la classe doit être la classe racine. Autrement dit, il doit y avoir une relation d'incorporation entre la classe racine et la nouvelle classe de domaine.
Si votre diagramme comporte des couloirs, le parent peut être la classe de domaine qui est mappée à un couloir. Avant de poursuivre cette procédure, consultez Définition d'une solution DSL avec des couloirs.
Ajoutez une classe de forme pour représenter les éléments sur le diagramme de modèle. Faites glisser de l'un des outils suivants sur le diagramme de définition DSL :
Forme géométrique fournit un rectangle ou une ellipse.
Forme d'image affiche une image que vous fournissez.
Forme de compartiment est un rectangle qui contient une ou plusieurs listes d'éléments.
Renommez la classe de forme, qui apparaîtra du côté droit du diagramme de définition DSL sous Formes et connecteurs.
Si vous avez créé une forme d'image, définissez une image.
Créez un fichier image de n'importe quelle taille. Les formats BMP, JPEG, GIF et EMF sont pris en charge.
Dans l'Explorateur de solutions, ajoutez le fichier à la solution sous Dsl\Resources.
Revenez au diagramme de définition DSL et sélectionnez la nouvelle classe de forme d'image.
Dans la fenêtre Propriétés, cliquez sur la propriété Image.
Dans la boîte de dialogue Sélectionner une image, cliquez sur le menu déroulant sous Nom de fichier et sélectionnez l'image.
Ajoutez des décorateurs de texte à la forme pour afficher les propriétés de domaine.
Pour afficher le nom ou le titre de l'élément de modèle, vous aurez probablement besoin d'au moins un décorateur de texte.
Cliquez avec le bouton droit sur l'en-tête de la classe de forme, pointez sur Ajouter, puis cliquez sur Décorateur de texte. Définissez le nom du décorateur et, dans la fenêtre Propriétés, définissez sa Position.
Connectez chaque forme avec un mappage d'élément de diagramme à la classe de domaine qu'elle doit afficher.
Cliquez sur l'outil Mappage d'élément de diagramme, sur la classe de domaine, puis sur la classe de forme.
Mappez les propriétés aux décorateurs de texte.
Sélectionnez la ligne grise entre la classe de domaine et la forme de classe qui représente le mappage d'élément de diagramme.
Dans la fenêtre Détails DSL, cliquez sur l’onglet Mappages de décorateurs. Si la fenêtre Détails DSL n’est pas visible, dans le menu Affichage, pointez sur Autres fenêtres, puis cliquez sur Détails DSL. Il est souvent nécessaire d'agrandir cette fenêtre vers le haut pour voir tout son contenu.
Sélectionnez le nom d'un décorateur. Sous Propriété d'affichage, sélectionnez le nom d'une propriété de la classe de domaine. Répétez cette opération pour chaque décorateur.
Si vous souhaitez afficher une propriété d'un élément associé, cliquez sur le navigateur d'arborescence déroulant sous Chemin d'accès à la propriété d'affichage.
Vérifiez qu'une coche apparaît à côté de chaque nom de décorateur.
Fabriquez un élément de boîte à outils pour créer des éléments de la classe de domaine.
Dans l'Explorateur DSL, développez le nœud Éditeur et tous ses sous-nœuds.
Cliquez avec le bouton droit sur le nœud situé sous Onglets de la boîte à outils, qui porte le même nom que votre solution DSL, par exemple BibliothèqueMusicale. Cliquez sur Ajouter un outil d'élément.
Notes
Si vous cliquez avec le bouton droit sur le nœud Outils, l'option Ajouter un outil d'élément n'apparaît pas. Cliquez plutôt sur le nœud juste au-dessus.
Dans la fenêtre Propriétés, sélectionnez le nouvel outil d'élément, définissez le paramètre Classe sur la classe de domaine que vous avez récemment ajoutée.
Définissez les paramètres Légende et Info-bulle.
Définissez le paramètre Icône de boîte à outils sur une icône qui apparaîtra dans la boîte à outils. Vous pouvez la définir sur une nouvelle icône ou sur une icône déjà utilisée pour un autre outil.
Pour créer une icône, ouvrez Dsl\Resources dans l'Explorateur de solutions. Copiez et collez l'un des fichiers BMP d'outil d'élément existants. Renommez la copie collée, puis double-cliquez dessus pour la modifier.
Revenez au diagramme de définition DSL, sélectionnez l'outil puis, dans la fenêtre Propriétés, cliquez sur [...] dans Icône de boîte à outils. Dans la boîte de dialogue Sélectionner l'image bitmap, sélectionnez votre fichier .BMP dans le menu déroulant.
Pour plus d’informations, consultez Propriétés des formes de géométrie et Propriétés des formes d'image.
Pour tester des formes
Cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions pour générer le code du concepteur DSL.
Générez et exécutez la solution DSL. Appuyez sur F5 ou Ctrl+F5 pour exécuter une nouvelle instance de Visual Studio en mode expérimental. Dans l'instance expérimentale de Visual Studio, ouvrez ou créez un fichier ayant l'extension de nom de fichier de votre solution DSL.
Vérifiez que les outils d'éléments apparaissent dans la boîte à outils.
Créez des formes en les faisant glisser depuis un outil vers le diagramme du modèle.
Vérifiez que chaque décorateur de texte apparaît, et que :
vous pouvez le modifier, sauf si vous avez défini l'indicateur Is UI Read Only sur la propriété de domaine.
quand vous modifiez la propriété dans la fenêtre Propriétés ou dans le décorateur, l'autre vue est mise à jour.
Après avoir testé une forme, vous souhaiterez peut-être ajuster certaines de ses propriétés et ajouter certaines fonctionnalités avancées. Pour plus d’informations, consultez Personnalisation et extension d'un langage spécifique à un domaine.
Définition des relations de référence
Vous pouvez définir une relation de référence entre n'importe quelle classe de domaine source et n'importe quelle classe de domaine cible. Les relations de référence sont généralement affichées sur un diagramme sous forme de connecteurs, qui sont des lignes entre des formes.
Par exemple, si Albums et Artistes sont affichés en tant que formes sur votre diagramme, vous pourriez définir une relation nommée ArtistesApparusSurAlbums qui relie des Artistes aux Albums sur lesquels ils ont travaillé. Voir l'exemple sur la figure.
Les relations de référence peuvent aussi lier des éléments du même type. Par exemple, dans une solution DSL représentant un arbre généalogique, la relation entre les parents et leurs enfants est une relation de référence de Personne à Personne.
Définir une relation de référence
Cliquez sur l'outil Relation de référence, sur la classe de domaine source de la relation, puis sur la classe de domaine cible. La classe cible peut être identique à la classe source.
Chaque relation à deux rôles, représentés par la ligne de chaque côté de la zone de relation. Vous pouvez sélectionner chaque rôle et définir ses propriétés dans la fenêtre Propriétés.
Renommez les rôles le cas échéant. Par exemple, dans une relation entre Personne et Personne, vous pourriez remplacer les noms par défaut par Parents et Enfants, Responsable et Subordonnés, Enseignant et Élève, et ainsi de suite.
Ajustez les multiplicités de chaque rôle si nécessaire. Si vous souhaitez que chaque Personne ait au plus un Responsable, affectez la valeur 0..1 à la multiplicité qui apparaît sous l'étiquette Responsable sur le diagramme.
Ajoutez des propriétés de domaine à la relation. Sur la figure, la relation Artist-Album a une propriété de rôle.
Définissez la propriété Autoriser les doublons de la relation, si plusieurs liens de la même classe peuvent exister entre la même paire d'éléments de modèle. Par exemple, vous pourriez autoriser un Enseignant à enseigner plusieurs Sujets au même Étudiant.
Pour plus d’informations, consultez Propriétés des relations de domaine et Propriétés des rôles de domaine.
Définir un connecteur pour afficher la relation
Un connecteur affiche une ligne entre deux formes sur le diagramme de modèle.
Faites glisser l'outil Connecteur sur le diagramme de définition DSL.
Ajoutez des décorateurs de texte si vous voulez afficher des étiquettes sur le connecteur. Définissez leurs positions. Pour permettre à l'utilisateur de déplacer un décorateur de texte, définissez sa propriété Is Moveable.
Utilisez l'outil Mappage d'élément de diagramme pour relier le connecteur à la relation de référence.
Avec le mappage d'élément de diagramme sélectionné, ouvrez la fenêtre Détails DSL et ouvrez l'onglet Mappages de décorateurs.
Sélectionnez chaque Décorateur et définissez la Propriété d'affichage à la propriété de domaine correcte.
Vérifiez qu'une coche apparaît à côté de chaque élément dans la liste Décorateurs.
Définir un outil générateur de connexion
Dans la fenêtre Explorateur DSL, développez le nœud Éditeur et tous ses sous-nœuds.
Cliquez avec le bouton droit sur le nœud ayant le même nom que votre solution DSL, puis cliquez sur Ajouter un nouvel outil de connexion.
Pendant que le nouvel outil est sélectionné, dans la fenêtre Propriétés :
Définissez la Légende et l'Info-bulle.
Cliquez sur Générateur de connexion et sélectionnez le générateur approprié pour la nouvelle relation.
Définissez le paramètre Icône de boîte à outils sur l'icône que vous souhaitez afficher dans la boîte à outils. Vous pouvez la définir sur une nouvelle icône ou sur une icône déjà utilisée pour un autre outil.
Pour créer une icône, ouvrez Dsl\Resources dans l'Explorateur de solutions. Copiez et collez l'un des fichiers BMP d'outil d'élément existants. Renommez la copie collée, puis double-cliquez dessus pour la modifier.
Revenez au diagramme de définition DSL, sélectionnez l'outil puis, dans la fenêtre Propriétés, cliquez sur [...] dans Icône de boîte à outils. Dans la boîte de dialogue Sélectionner l'image bitmap, sélectionnez votre fichier .BMP dans le menu déroulant.
Pour tester un connecteur et une relation de référence
Cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions pour générer le code du concepteur DSL.
Générez et exécutez la solution DSL. Appuyez sur F5 ou Ctrl+F5 pour exécuter une nouvelle instance de Visual Studio en mode expérimental. Dans l'instance expérimentale de Visual Studio, ouvrez ou créez un fichier ayant l'extension de nom de fichier de votre solution DSL.
Vérifiez que l'outil de connexion apparaît dans la boîte à outils.
Créez des formes en les faisant glisser depuis un outil vers le diagramme du modèle.
Créez des connexions entre les formes. Cliquez sur l'outil de connecteur, cliquez sur une forme, puis sur une autre forme.
Vérifiez que vous ne pouvez pas créer des connexions entre des classes inappropriées. Par exemple, si votre relation est entre Albums et Artistes, vérifiez que vous ne pouvez pas lier Artistes à Artistes.
Vérifiez que les multiplicités sont correctes. Par exemple, vérifiez que vous ne pouvez pas connecter une Personne à plusieurs Responsables.
Vérifiez que chaque décorateur de texte apparaît, et que :
vous pouvez le modifier, sauf si vous avez défini l'indicateur Is UI Read Only sur la propriété de domaine.
quand vous modifiez la propriété dans la fenêtre Propriétés ou dans le décorateur, l'autre vue est mise à jour.
Après avoir testé un connecteur, vous souhaiterez peut-être ajuster certaines de ses propriétés et ajouter certaines fonctionnalités avancées. Pour plus d’informations, consultez Personnalisation et extension d'un langage spécifique à un domaine.
Définition de formes qui contiennent des listes : formes de compartiments
Une forme de compartiment contient une ou plusieurs listes d'éléments. Par exemple, dans une solution DSL de bibliothèque musicale, vous pourriez utiliser des formes de compartiments pour représenter des albums. Dans chaque album figure une liste de morceaux.
Dans une définition DSL, le moyen le plus simple d'obtenir cet effet consiste à définir une classe de domaine pour le conteneur et une classe de domaine pour chaque liste. La classe de conteneur est mappée à la forme de compartiment.
Pour plus d’informations, consultez Propriétés des formes de compartiment.
Pour définir une forme de compartiment
Créez la classe de domaine de conteneur. Cliquez sur l'outil Relation d'incorporation, sur la classe racine du modèle, puis sur une partie vierge du diagramme de définition DSL. Cela crée la classe domaine nommée Album dans la figure de l'exemple.
En guise d'alternative, au lieu d'incorporer dans la classe racine, vous pouvez incorporer le conteneur dans une classe de domaine mappée à un couloir.
Ajoutez une propriété de domaine telle que Nom à la classe et définissez son indicateur Is Element Name dans la fenêtre Propriétés.
Créez la classe de domaine d'élément de liste. Cliquez sur l'outil Relation d'incorporation, sur la classe conteneur (Album), puis sur une partie vierge du diagramme. Cela crée la classe domaine nommée Song dans la figure de l'exemple.
Ajoutez une propriété de domaine telle que Titre à la classe et définissez son indicateur Is Element Name.
Ajoutez d'autres propriétés de domaine.
Ajoutez une autre classe de domaine d'élément de liste pour chaque liste que vous souhaitez afficher.
Pour combiner plusieurs types d'éléments dans la liste, créez des classes qui héritent de la classe de liste. Rendez la classe de liste abstraite en définissant son Modificateur d'héritage.
Par exemple, si vous souhaitez que la musique classique soit triée par compositeur plutôt que par artiste, vous pourriez créer deux sous-classes de Morceau, Morceau_Classique et Morceau_Non_Classique.
Créez la forme de compartiment. Faites glisser à partir de l'outil Forme de compartiment sur le diagramme de définition DSL.
Ajoutez un décorateur de texte et définissez son nom.
Ajoutez un compartiment et définissez son nom.
Pour permettre à l'utilisateur de masquer les compartiments de listes, cliquez avec le bouton droit sur la classe de forme, pointez sur Ajouter, puis cliquez sur Développer/réduire le décorateur. Dans la fenêtre Propriétés, définissez la position du décorateur.
Cliquez sur l'outil Mappage d'élément de diagramme, sur la classe de domaine de conteneur, puis sur la forme de compartiment.
Sélectionnez le lien de mappage d'élément de diagramme entre la classe de domaine et la forme. Dans la fenêtre Détails DSL :
Cliquez sur l'onglet Décorateurs. Cliquez sur le nom du décorateur, puis sélectionnez l'élément approprié sous Propriété d'affichage. Vérifiez qu'une coche apparaît à côté du nom du décorateur.
Cliquez sur l'onglet Mappages de compartiments.
Cliquez sur le nom du compartiment.
Sous Chemin d'accès à la collection d'éléments affichés, naviguez jusqu'à la classe d'éléments de liste (Song). Cliquez sur la flèche déroulante pour utiliser l'outil de navigation.
Sous Propriété d'affichage, sélectionnez la propriété qui doit être affichée dans la liste. Dans l'exemple, il s'agit de Title.
Notes
En utilisant les champs Chemin d'accès dans les champs Mappage de décorateur et Mappage de compartiment, vous pouvez créer des relations plus complexes entre les classes de domaine et la forme de compartiment.
Pour définir un outil pour la création de la forme
Fabriquez un élément de boîte à outils pour créer des éléments de la classe de domaine.
Dans l'Explorateur DSL, développez le nœud Éditeur et tous ses sous-nœuds.
Cliquez avec le bouton droit sur le nœud situé sous Onglets de la boîte à outils, qui porte le même nom que votre solution DSL, par exemple BibliothèqueMusicale. Cliquez sur Ajouter un outil d'élément.
Notes
Si vous cliquez avec le bouton droit sur le nœud Outils, l'option Ajouter un outil d'élément n'apparaît pas. Cliquez plutôt sur le nœud juste au-dessus.
Dans la fenêtre Propriétés, sélectionnez le nouvel outil d'élément, définissez le paramètre Classe sur la classe de domaine que vous avez récemment ajoutée.
Définissez les paramètres Légende et Info-bulle.
Définissez le paramètre Icône de boîte à outils sur une icône qui apparaîtra dans la boîte à outils. Vous pouvez la définir sur une nouvelle icône ou sur une icône déjà utilisée pour un autre outil.
Pour créer une icône, ouvrez Dsl\Resources dans l'Explorateur de solutions. Copiez et collez l'un des fichiers .BMP d'outil d'élément existants. Renommez la copie collée, puis double-cliquez dessus pour la modifier.
Revenez au diagramme de définition DSL, sélectionnez l'outil puis, dans la fenêtre Propriétés, cliquez sur [...] dans Icône de boîte à outils. Dans la boîte de dialogue Sélectionner l'image bitmap, sélectionnez votre fichier BMP dans le menu déroulant.
Pour tester une forme de compartiment
Cliquez sur Transformer tous les modèles dans la barre d'outils de l'Explorateur de solutions pour générer le code du concepteur DSL.
Générez et exécutez la solution DSL. Appuyez sur F5 ou Ctrl+F5 pour exécuter une nouvelle instance de Visual Studio en mode expérimental. Dans l'instance expérimentale de Visual Studio, ouvrez ou créez un fichier ayant l'extension de nom de fichier de votre solution DSL.
Vérifiez que l'outil apparaît dans la boîte à outils.
Faites glisser l'outil sur le diagramme de modèle. Une forme est créée.
Vérifiez que le nom de l'élément apparaît et qu'il est défini automatiquement à une valeur par défaut.
Cliquez avec le bouton droit sur l’en-tête de la nouvelle forme, puis cliquez sur Ajouter Votre élément de liste. Dans l’exemple, la commande est Add Song.
Vérifiez qu'un élément apparaît dans la liste et qu'il a un nouveau nom.
Cliquez sur l'un des éléments de la liste, puis examinez la fenêtre Propriétés. Vous devez voir les propriétés des éléments de liste.
Ouvrez l'explorateur de langage. Vérifiez que les nœuds conteneurs sont visibles, avec les nœuds d'éléments de liste à l'intérieur.
Après avoir testé une forme de compartiment, vous souhaiterez peut-être ajuster certaines de ses propriétés et ajouter certaines fonctionnalités avancées. Pour plus d’informations, consultez Personnalisation et extension d'un langage spécifique à un domaine.
Affichage d'un lien de référence dans un compartiment
En général, un élément que vous affichez dans un compartiment est un enfant de l'élément qui représenté par la forme de compartiment. Mais parfois, vous souhaitez afficher un élément qui y est lié avec une relation de référence.
Par exemple, nous pourrions ajouter un second compartiment à AlbumShape qui affiche une liste des artistes liés à l'album.
Dans ce cas, le compartiment doit afficher le lien au lieu de l'élément référencé. En effet, quand l’utilisateur sélectionne l’élément dans l’emplacement et qu'il appuie sur DELETE
, vous souhaitez supprimer le lien, et non l'élément référencé.
Néanmoins, vous pouvez faire en sorte d'afficher l'élément référencé dans le compartiment.
La procédure suivante part du principe que vous avez déjà créé la classe de domaine, la relation de référence, la forme de compartiment et le mappage d'élément de diagramme, comme décrit précédemment dans cette section.
Pour afficher un lien de référence dans un compartiment
Ajoutez un compartiment à la forme de compartiment. Sur le diagramme de définition DSL, cliquez avec le bouton droit sur la classe de forme de compartiment, pointez sur Ajouter, puis cliquez sur Compartiment.
Définissez Chemin d'accès à la collection d'éléments affichés pour naviguer jusqu'au lien plutôt qu'à son élément cible. Cliquez sur le menu déroulant et utilisez l'arborescence pour sélectionner la relation de référence au lieu de sa cible. Dans l'exemple, la relation est ArtistAppearedOnAlbums.
Définissez Chemin d'accès à la propriété d'affichage pour naviguer du lien à l'élément cible. Dans l'exemple, il s'agit d'Artist.
Définissez Propriété d'affichage sur la propriété appropriée de l'élément cible, par exemple Name.
Transformez tous les modèles, générez et exécutez la solution DSL, puis ouvrez un modèle test.
Dans le diagramme de modèle, créez les classes de forme appropriées, définissez leurs noms, puis créez un lien entre elles. Dans la forme de compartiment, les noms des éléments liés doivent apparaître.
Sélectionnez le lien ou l'élément dans la forme de compartiment. Le lien et l'élément doivent tous deux apparaître.
Définition de ports à la limite d'une autre forme
Un port est une forme qui se trouve à la limite d'une autre forme.
Les ports peuvent aussi servir à fournir un point de connexion fixe sur une autre forme, sur lequel l'utilisateur peut dessiner des connecteurs. Dans ce cas, vous pouvez rendre la forme de port transparente.
Pour voir un exemple qui utilise les ports, sélectionnez le modèle Diagramme de composant quand vous créez une solution DSL. Cet exemple montre les points principaux à prendre en compte lors de la définition des ports :
Il existe une classe de domaine qui représente le conteneur des ports,
Component
.Il existe une classe de domaine qui représente des ports. dans l’exemple, il s’agit de
ComponentPort
.Il existe une relation d'incorporation de la classe de domaine de conteneur à la classe de domaine de port. Pour plus d'informations, consultez Définition des classes de domaine.
Si vous souhaitez que différents types de ports soient combinés sur le même conteneur, vous pouvez créer des sous-classes de la classe de domaine de port. Dans l'exemple,
InPort
etOutPort
héritent deComponentPort
.La classe de domaine de conteneur peut être mappée à n'importe quel type de forme. Dans l'exemple, il s'agit de
ComponentShape
. Pour plus d'informations, consultez Définition des formes.Les classes de domaine de port sont mappées à des formes de ports. Vous pouvez soit mapper les classes dérivées à des classes de formes de ports distinctes, soit mapper la classe de base à une classe de forme de port.
À d'autres égards, les formes de ports se comportent comme décrit dans Définition des formes.
Pour plus d’informations, consultez Propriétés des formes de port.
Définition d'une solution DSL avec des couloirs
Les couloirs sont des partitions horizontales ou verticales d'un diagramme. Chaque couloir correspond à un élément de modèle. Votre définition DSL nécessite une classe de domaine pour les éléments de couloirs.
Le meilleur moyen de créer une solution DSL avec des couloirs consiste à créer une solution DSL et à choisir le modèle de solution Flux de tâches. Dans la définition DSL, la classe Acteur est la classe de domaine mappée au couloir. Renommez celle-ci et les autres classes en fonction de votre projet.
Pour ajouter une classe qui sera affichée en tant que forme à l'intérieur d'un couloir, créez une relation d'incorporation entre la classe de couloir et votre nouvelle classe. Les utilisateurs pourront faire glisser des éléments d'un couloir à un autre, mais chaque élément sera toujours à l'intérieur d'un couloir particulier. Dans le modèle de solution Flux de tâches, FlowElement est un enfant de la classe de couloir.
Pour ajouter une classe qui sera affichée en tant que forme indépendamment des couloirs, créez une relation d'incorporation entre la classe racine et votre nouvelle classe. Les utilisateurs pourront placer ces formes n'importe où sur le diagramme, y compris de chaque côté des limites des couloirs et en dehors des couloirs. Dans le modèle de solution Flux de tâches, Comment est un enfant de la classe racine.
Pour plus d’informations, consultez Propriétés des couloirs.
Ajout de types de propriétés
Littéraux et énumérations de domaine
Une énumération de domaine est un type avec plusieurs valeurs littérales.
Pour ajouter une énumération de domaine, cliquez avec le bouton droit sur la racine du modèle dans l'Explorateur DSL, puis cliquez sur Ajouter une nouvelle énumération de domaine. L'élément apparaîtra dans l'Explorateur DSL sous le nœud Types de domaines. Cet élément n'apparaît pas sur le diagramme.
Pour ajouter des littéraux d'énumération à l'énumération de domaine, cliquez avec le bouton droit sur l'énumération de domaine dans l'Explorateur DSL, puis cliquez sur Ajouter un nouveau littéral d'énumération.
Par défaut, une propriété qui a un type d'énumération ne peut être définie qu'à une seule valeur de l'énumération à la fois. Si vous souhaitez que les utilisateurs et les programmeurs puissent définir n'importe quelle combinaison de valeurs (un « champ de bits »), définissez la propriété IsFlags de l'énumération.
Types externes
Quand vous définissez le type d'une propriété de domaine, si vous ne trouvez pas le type souhaité dans la liste déroulante Type, vous pouvez ajouter un type externe. Par exemple, vous pourriez ajouter le type System.Drawing.Color à la liste.
Pour ajouter un type, cliquez avec le bouton droit sur la racine du modèle dans l'Explorateur DSL, puis cliquez sur Ajouter un nouveau type externe. Dans la fenêtre Propriétés, définissez le nom sur Color et l’espace de noms sur System.Drawing. Ce type apparaît maintenant dans l'Explorateur DSL sous Types de domaines. Vous pouvez le choisir chaque fois que vous définissez le type d'une propriété de domaine.
Personnalisation de la solution DSL
À l'aide des techniques décrites dans cette rubrique, vous pouvez rapidement créer une solution DSL avec une notation visuelle, un formulaire XML lisible et les outils de base nécessaires pour générer du code et d'autres artefacts.
Il existe deux méthodes pour étendre la définition DSL :
Affinez la solution DSL en utilisant davantage de fonctionnalités de la définition DSL. Par exemple, vous pouvez créer un outil connecteur capable de créer plusieurs types de connecteurs et vous pouvez contrôler les règles selon lesquelles la suppression d'un élément supprime également les éléments associés. Ces techniques nécessitent la plupart du temps la définition de valeurs dans la définition DSL et certaines nécessitent quelques lignes de code de programme.
Pour plus d’informations, consultez Personnalisation et extension d'un langage spécifique à un domaine.
Étendez vos outils de modélisation à l'aide de code de programme pour obtenir des effets avancés. Par exemple, vous pouvez créer des commandes de menu qui peuvent modifier le modèle et vous pouvez créer des outils qui intègrent plusieurs solutions DSL. Le Kit VMSDK a été conçu spécifiquement pour simplifier l'intégration à vos extensions avec le code généré à partir de la définition DSL. Pour plus d’informations, consultez l’article Écrire du code pour personnaliser un langage spécifique à un domaine.
Modification de la définition DSL
Quand vous créez un élément dans une définition DSL, de nombreuses valeurs par défaut sont définies automatiquement. Une fois ces valeurs définies, vous pouvez les modifier. Cela simplifie le développement des solutions DSL tout en permettant d'effectuer de puissantes personnalisations.
Par exemple, quand vous mappez une forme à un élément, le chemin d'accès à l'élément parent du mappage est défini automatiquement en fonction de la relation d'incorporation de la classe de domaine. Toutefois, si vous modifiez ultérieurement la relation d'incorporation, le chemin d'accès à l'élément parent n'est pas modifié automatiquement.
Vous devez donc savoir que quand vous modifiez certaines relations dans votre définition DSL, il n'est pas rare que des erreurs soient signalées quand vous enregistrez la définition ou quand vous transformez tous les modèles. La plupart de ces erreurs sont faciles à corriger. Double-cliquez sur le rapport d'erreur pour afficher l'emplacement de l'erreur.
Voir aussi Comment : modifier l'espace de nom d'un langage spécifique à un domaine.
Dépannage
Le tableau suivant mentionne certains des problèmes les plus courants qui peuvent être rencontrés lors de la conception d'une solution DSL, avec quelques suggestions de solution. D’autres conseils sont disponibles sur le forum d’extensibilité des outils de visualisation.
Problème | Suggestion |
---|---|
Les modifications que j'ai apportées dans le fichier de définition DSL n'ont aucun effet. | Cliquez sur Transformer tous les modèles dans la barre d'outils au-dessus de l'Explorateur de solutions, puis regénérez la solution. |
Les formes indiquent le nom d'un décorateur au lieu de la valeur de propriété. | Configurez le mappage de décorateur. Sur le diagramme de définition DSL, cliquez sur le mappage d'élément de diagramme, c'est-à-dire la ligne grise entre la classe de domaine et la classe de forme. Ouvrez la fenêtre Détails DSL. Si elle n'est pas visible, dans le menu Affichage, pointez sur Autres fenêtres, puis cliquez sur Détails DSL. Cliquez sur l’onglet Mappages de décorateurs. Sélectionnez le nom du décorateur. Vérifiez que la case correspondante est cochée. Sous Propriété d'affichage, sélectionnez le nom d'une propriété de domaine. Pour plus d'informations, consultez Formes sur le diagramme. |
Dans l'Explorateur DSL, je ne parviens pas à ajouter de collection. Par exemple, quand je clique avec le bouton droit sur Outils, il n'y a pas de commande « Ajouter un outil » dans le menu. Dans l'explorateur de ma solution DSL, je ne parviens pas à ajouter d'élément à une liste. |
Cliquez avec le bouton droit sur l'élément au-dessus du nœud concerné. Quand vous souhaitez ajouter un élément à une liste, la commande Ajouter ne se trouve pas dans le nœud de la liste, mais dans son propriétaire. |
J'ai créé une classe de domaine, mais je ne parviens pas à créer d'instances dans l'explorateur de langage. | Chaque classe de domaine, à l'exception de la racine, doit être la cible d'une relation d'incorporation. |
Dans l'explorateur de ma solution DSL, les éléments sont affichés uniquement avec leur nom de type. | Dans la définition DSL, sélectionnez une propriété de domaine de la classe et, dans la fenêtre Propriétés, affectez la valeur True à Is Element Name. |
Ma solution DSL s'ouvre toujours dans l'éditeur XML. | Cela peut être dû à une erreur lors de la lecture du fichier. Toutefois, même après avoir corrigé cette erreur, vous devez réinitialiser de manière explicite l'éditeur pour qu'il soit votre concepteur DSL. Cliquez avec le bouton droit sur l'élément de projet, cliquez sur Ouvrir avec, puis sélectionnez Votre_LangageConcepteur (par défaut). |
La boîte à outils de ma solution DSL n'apparaît pas après que j'ai modifié les noms des assemblys. | Inspectez et mettez à jour DslPackage\GeneratedCode\Package.tt Pour plus d’informations, consultez Comment : modifier l'espace de nom d'un langage spécifique à un domaine. |
La boîte à outils de ma solution DSL n'apparaît pas, mais je n'ai pas modifié le nom de l'assembly. Ou une boîte de message apparaît et signale l'échec du chargement d'une extension. |
Réinitialisez l'instance expérimentale et regénérez votre solution. 1. Dans le menu Démarrer de Windows, sous Tous les programmes, développez Kit de développement logiciel Visual Studio, ensuite Outils, puis cliquez sur Réinitialiser l’instance expérimentale de Microsoft Visual Studio. 2. Dans le menu Générer, cliquez sur Régénérer la solution. |