Partager via


Ajout d'une validation d'architecture personnalisée aux diagrammes de couche

Dans Visual Studio 2010 Ultimate et Visual Studio 2010 Premium, les utilisateurs peuvent valider le code source dans un projet Visual Studio par rapport à un modèle de couche pour pouvoir vérifier que le code source est conforme aux dépendances sur un diagramme de couche. Il existe un algorithme de validation standard, mais ce Feature Pack Visual Studio 2010 vous permet de définir vos propres extensions de validation pour Visual Studio Ultimate et Visual Studio Premium. Pour plus d'informations, consultez Packs de fonctionnalités Visual Studio.

Lorsque l'utilisateur sélectionne la commande Validate Architecture sur un diagramme de couche, la méthode de validation standard est appelée, suivie par toutes extensions de validation installées.

Notes

La validation dans un diagramme de couche n'est pas la même que la validation dans les diagrammes UML. Dans un diagramme de couche, le but principal est de comparer le diagramme avec le code de programme dans d'autres parties de la solution.

Vous pouvez empaqueter votre extension de validation de couche dans une extension d'intégration Visual Studio (VSIX) et la distribuer à d'autres utilisateurs Visual Studio Ultimate. Vous pouvez placer votre validateur seul dans un projet VSIX ou le combiner dans le même projet VSIX que d'autres extensions. Vous devez écrire le code du validateur dans son propre projet Visual Studio, pas dans le même projet que d'autres extensions.

Spécifications

Pour obtenir les spécifications et les instructions nécessaires à l'installation, consultez Spécifications dans Création d'extensions de diagrammes de couche.

Définition d'un validateur de couche dans un nouveau projet VSIX

La méthode la plus rapide pour créer un validateur consiste à utiliser le modèle de projet. Cela place le code et le manifeste VSIX dans le même projet.

Pour définir une extension à l'aide d'un modèle de projet

  1. Créez un projet dans une nouvelle solution, en utilisant la commande Nouveau projet dans le menu Fichier.

  2. Dans la boîte de dialogue Nouveau projet, sous Projets de modélisation, sélectionnez Layer Designer Validation Extension (Extension de validation de concepteur de couche).

    Le modèle crée un projet qui contient un petit exemple.

  3. Modifiez le code pour définir votre validation. Pour plus d'informations, consultez Programmation de la validation.

  4. Pour tester l'extension, consultez Débogage de la validation de couche.

    Notes

    Votre méthode sera appelée uniquement dans des circonstances spécifiques, et les points d'arrêt ne fonctionneront pas automatiquement. Pour plus d'informations, consultez Débogage de la validation de couche.

  5. Pour installer l'extension dans l'instance principale de Visual Studio ou sur un autre ordinateur, recherchez le fichier .vsix dans bin\*. Copiez-le sur l'ordinateur sur lequel vous souhaitez l'installer, puis double-cliquez dessus. Pour le désinstaller, utilisez le Gestionnaire d'extensions dans le menu Outils.

Ajout d'un validateur de couche à un projet VSIX séparé

Si vous souhaitez créer un VSIX qui contient des validateurs de couche, des commandes et d'autres extensions, nous vous recommandons de créer un projet pour définir le VSIX et des projets séparés pour les gestionnaires. Pour plus d'informations sur les autres types d'extensions de modélisation, consultez l'article Extension de modèles et de diagrammes UML.

Pour ajouter la validation de couche à un VSIX séparé

  1. Créez un projet de bibliothèque de classes dans une solution Visual Studio Ultimate nouvelle ou existante. Dans la boîte de dialogue Nouveau projet, cliquez sur Visual C#, puis sur Bibliothèque de classes. Ce projet contiendra la classe de validation de couche.

  2. Identifiez ou créez un projet VSIX dans votre solution. Un projet VSIX contient un fichier nommé source.extension.vsixmanifest. Si vous devez ajouter un projet VSIX, suivez ces étapes :

    1. Dans la boîte de dialogue Nouveau projet, développez Visual C#, cliquez sur Extensibilité, puis sur Projet VSIX.

    2. Dans l'Explorateur de solutions, cliquez avec le bouton droit sur le projet VSIX, puis cliquez sur Définir comme projet de démarrage.

    3. Cliquez sur Sélectionner des éditions et assurez-vous que Visual Studio Ultimate est sélectionné.

  3. Dans source.extension.vsixmanifest, sous Contenu, ajoutez le projet de validation de couche comme un composant MEF :

    1. Cliquez sur Ajouter du contenu.

    2. Dans Sélectionner un type de contenu, sélectionnez Composant MEF.

    3. Sous Sélectionner une source, cliquez sur Projet et sélectionnez le nom du projet de votre gestionnaire de mouvements ou de commandes.

    4. Enregistrez le fichier.

  4. Ajoutez le projet de validation de couche comme une extension personnalisée :

    1. Cliquez sur Ajouter du contenu.

    2. Dans Sélectionner un type de contenu, sélectionnez Type d'extension personnalisée.

    3. Dans Type, entrez Microsoft.VisualStudio.ArchitectureTools.Layer.Validator

    4. Dans Sélectionner une source, cliquez sur Projet, puis sélectionnez le nom de votre projet de bibliothèque de classes de validation.

  5. Sous Références, cliquez sur Ajouter une référence, puis sélectionnez le Runtime de ce Feature Pack.

  6. Revenez au projet de validation de couche et ajoutez les références de projet suivantes :

    Référence

    Actions autorisées

    Si Visual Studio 2010 Visualization and Modeling Feature Pack est installé :

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.GraphModel.dll

    Si Microsoft Visual Studio 2010 Feature Pack 2 est installé :

    …\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.GraphModel.dll

    Lire le graphique d'architecture

    Si Visual Studio 2010 Visualization and Modeling Feature Pack est installé :

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll

    Si Microsoft Visual Studio 2010 Feature Pack 2 est installé :

    …\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\ Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll

    Lire le code DOM associé aux couches

    Si Visual Studio 2010 Visualization and Modeling Feature Pack est installé :

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll

    Si Microsoft Visual Studio 2010 Feature Pack 2 est installé :

    …\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\Visualization and Modeling Feature Pack Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll

    Lire le modèle de couche

    Microsoft.VisualStudio.Uml.Interfaces

    Lire le modèle de couche

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Lire et mettre à jour les formes et les diagrammes

    System.ComponentModel.Composition

    Définir le composant de validation à l'aide de Managed Extensibility Framework (MEF)

    Microsoft.VisualStudio.Modeling.Sdk.10.0

    Définir des extensions de modélisation

    Notes

    %LocalAppData% est en général NomLecteur:\Users\NomUtilisateur\AppData\Local. Sous Windows XP ou Windows 2003, utilisez %AppData% au lieu de %LocalAppData%.

  7. Modifiez le fichier de classe dans le projet de bibliothèque de classes C# pour qu'il contienne le code de votre validation. Pour plus d'informations, consultez Programmation de la validation.

  8. Pour tester l'extension, consultez Débogage de la validation de couche.

    Notes

    Votre méthode sera appelée uniquement dans des circonstances spécifiques, et les points d'arrêt ne fonctionneront pas automatiquement. Pour plus d'informations, consultez Débogage de la validation de couche.

  9. Pour installer le VSIX dans l'instance principale de Visual Studio ou sur un autre ordinateur, recherchez le fichier .vsix dans le répertoire bin du projet VSIX. Copiez-le sur l'ordinateur sur lequel vous souhaitez installer le VSIX. Double-cliquez sur le fichier VSIX dans l'Explorateur Windows.

    Pour le désinstaller, utilisez le Gestionnaire d'extensions dans le menu Outils.

Programmation de la validation

Pour définir une extension de validation de couche, définissez une classe avec les caractéristiques suivantes :

  • La forme générale de la déclaration se présente comme suit :

      [Export(typeof(IValidateArchitectureExtension))]
      public partial class Validator1Extension :
                      IValidateArchitectureExtension
      {
        public void ValidateArchitecture(Graph graph)
        {
          var typeCategory = graph.DocumentSchema
                     .Categories.Get("CodeSchema_Type");
          var allTypes = graph.Nodes.GetByCategory(typeCategory);
        ...
          this.LogValidationError(graph, "SampleErrorId", 
             "Sample Validation Error", GraphErrorLevel.Error, allTypes);
        }
    
  • Lorsque vous découvrez une erreur, vous pouvez la signaler à l'aide de LogValidationError().

Lorsque l'utilisateur appelle la commande de menu Valider l'architecture, le système runtime de couche analyse les couches et leurs artefacts pour produire un graphique. Le graphique se compose de quatre parties :

  • Les modèles de couche de la solution Visual Studio représentés comme des nœuds et des liens dans le graphique.

  • Le code, les éléments de projet et d'autres artefacts qui sont définis dans la solution et sont représentés comme des nœuds, et les liens qui représentent les dépendances découvertes par le processus d'analyse.

  • Les liens des nœuds de couche vers les nœuds d'artefact de code.

  • Les nœuds qui représentent des erreurs découvertes par le validateur.

Une fois le graphique construit, la méthode de validation standard est appelée. Lorsqu'elle se termine, toutes les méthodes de validation d'extension installées sont appelées dans un ordre non spécifié. Le graphique est passé à chaque méthode ValidateArchitecture, qui peut l'analyser et signaler toutes les erreurs qu'elle rencontre.

Notes

Cette opération diffère du processus de validation appliqué aux diagrammes UML et du processus de validation qui peut être utilisé dans des langages spécifiques à un domaine.

Les méthodes de validation ne doivent pas modifier le modèle de couche ou le code validé.

Le modèle de graphique est défini dans Microsoft.VisualStudio.GraphModel. Ses classes principales sont Node et Link.

Chaque nœud et chaque lien a une ou plusieurs catégories qui spécifient le type d'élément ou de relation qu'il représente. Les nœuds d'un graphique typique ont les catégories suivantes :

  • Dsl.LayerModel

  • Dsl.Layer

  • Dsl.Reference

  • CodeSchema_Type

  • CodeSchema_Namespace

  • CodeSchema_Type

  • CodeSchema_Method

  • CodeSchema_Field

  • CodeSchema_Property

Les liens des couches vers les éléments dans le code ont la catégorie « Représente ».

Le code suivant est un exemple typique d'une extension de validation d'architecture. Il vérifie que chaque type déclaré dans le code de la solution est référencé au moins une fois par le modèle de couche. L'utilisateur peut contrôler si cette validation doit être exécutée sur chaque modèle de couche en définissant une propriété personnalisée booléenne du modèle.

Si une erreur est rencontrée, LogValidationError est appelée.

Débogage de la validation

Pour déboguer votre extension de validation de couche, appuyez sur CTRL+F5. Une instance expérimentale de Visual Studio s'ouvre alors. Dans cette instance, ouvrez ou créez un modèle de couche. Ce modèle doit être associé au code et doit avoir au moins une dépendance.

Test avec une solution qui contient des dépendances

La validation n'est exécutée que si les caractéristiques suivantes sont présentes :

  • Il existe au moins un lien de dépendance sur le diagramme de couche.

  • Le modèle contient des couches associées aux éléments de code.

La première fois que vous démarrez une instance expérimentale de Visual Studio pour tester votre extension de validation, ouvrez ou créez une solution avec ces caractéristiques.

Exécuter la commande Nettoyer la solution avant de valider l'architecture

Chaque fois que vous mettez à jour votre code de validation, utilisez la commande Nettoyer la solution dans le menu Générer de la solution expérimentale, avant de tester la commande Valider. Cela est nécessaire car les résultats de la validation sont mis en cache. Si vous n'avez pas mis à jour le diagramme de couche de test ou son code, les méthodes de validation ne seront pas exécutées.

Lancer le débogueur explicitement

La validation s'exécute dans un processus séparé. Par conséquent, les points d'arrêt dans votre méthode de validation ne seront pas déclenchés. Vous devez joindre explicitement le débogueur au processus lorsque la validation a démarré.

Pour joindre le débogueur au processus de validation, insérez un appel à System.Diagnostics.Debugger.Launch() au démarrage de votre méthode de validation. Lorsque la boîte de dialogue de débogage s'affiche, sélectionnez l'instance principale de Visual Studio.

Vous pouvez également insérer un appel à System.Windows.Forms.MessageBox.Show(). Lorsque la boîte de message s'affiche, accédez à l'instance principale de Visual Studio et dans le menu Déboguer, cliquez sur Attacher au processus. Sélectionnez le processus appelé Graphcmd.exe.

Démarrez toujours l'instance expérimentale en appuyant sur CTRL+F5 (Exécuter sans débogage).

Déploiement d'une extension de validation

Pour installer votre extension de validation sur un ordinateur sur lequel Visual Studio Ultimate ou Visual Studio Premium est installé, ouvrez le fichier VSIX sur l'ordinateur cible. Pour l'installer sur un ordinateur sur lequel Team Foundation Build est installé, vous devez extraire manuellement le contenu de VSIX dans un dossier Extensions. Pour plus d'informations, consultez Déploiement d'une extension de modélisation de couche.

Exemple

L'exemple suivant illustre une extension de validation de couche.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema;

using Microsoft.VisualStudio.GraphModel;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer;

namespace MyValidationExtensions
{ // This attribute identifies a layer validator:
  [Export(typeof(IValidateArchitectureExtension))]
  public partial class UnreferencedTypeValidatorExtension 
      : IValidateArchitectureExtension
  {
    private GraphCategory typeCategory = null;
    /// <summary>
    /// Validate the architecture
    /// </summary>
    /// <param name="graph">The graph</param>
    public void ValidateArchitecture(Graph graph)
    {
      // A good place to attach a debugger
      // System.Windows.Forms.MessageBox.Show("Attach - Unreferenced Type Validator");
      // To find the nodes that represent the code and the layers,
      // we need to filter by category.
      // Categories are identified by specific strings:
      if (typeCategory == null)
      {
        typeCategory = 
          graph.DocumentSchema.Categories.Get("CodeSchema_Type");
      }
      var layerModelCategory = 
        graph.DocumentSchema.Categories.Get("Dsl.LayerModel");
      var allLayerModels =
        graph.Nodes.GetByCategory(layerModelCategory);

      foreach (var layerModel in allLayerModels)
      {
        var allTypesMustBeReferencedProperty =
           ExtractProperty(layerModel, 
            AllTypesMustBeReferencedProperty.FullName);
        bool shouldAllTypesBeReferenced = 
          allTypesMustBeReferencedProperty == null 
          ? false 
          : Convert.ToBoolean(allTypesMustBeReferencedProperty);

        if (shouldAllTypesBeReferenced)
        {
          // Find all types referenced by layers:
          var referencedTypes = new HashSet<Node>();
          GetReferencedTypes(referencedTypes, layerModel);
          var allTypes = graph.Nodes.GetByCategory(typeCategory);

          foreach (var type in allTypes)
          {
            if (!referencedTypes.Contains(type))
            {
              // Filter out types that are not part of any 
              // assembly (for example referenced external types).
              if (type.GetContainmentSources(graph)
                .Where(n => n.HasCategory(graph.DocumentSchema
                .Categories.Get("CodeSchema_Assembly"))).Any())
              {
                // type is not referenced in the layer diagram
                this.LogValidationError(graph,
                    string.Format("{0}_UnreferencedTypeError_{1}",
                    GetFullyQualifiedTypeName(type), Guid.NewGuid()),
                    string.Format("AV1002 : Unreferenced type :"
                      + " {0}{2}Layer Diagram: {1}.layerdiagram.",
                        GetFullyQualifiedTypeName(type),
                        layerModel.Label,
                        Environment.NewLine),
                    GraphErrorLevel.Error,
                    new Node[] { type });
              }
            }
          }
        }
      }
    }

    private void GetReferencedTypes(HashSet<Node> referencedTypes, Node node)
    {
      foreach (Node containedNode in node.GetContainmentTargets(node.Owner))
      {
        if (referencedTypes.Contains(containedNode))
        {
          // We've seen this node before
          continue;
        }

        if (containedNode.HasCategory(typeCategory))
        {
          referencedTypes.Add(containedNode);
        }
        else
        {
          GetReferencedTypes(referencedTypes, containedNode);
        }
      }
    }
    public static string GetFullyQualifiedTypeName(Node typeNode)
    {
      try
      {
         string returnValue;
         CodeQualifiedIdentifierBuilder id = 
           new CodeQualifiedIdentifierBuilder(
                   typeNode.Id, typeNode.Owner);
         returnValue = id.GetFullyQualifiedLabel(
              CodeQualifiedIdentifierBuilder.LabelFormat
              .NoAssemblyPrefix);
        return returnValue;
      }
      catch { }
     return typeNode.Label;
  }

  public static object ExtractProperty
             (Node layerModel, string propertyName)
  {
    object propertyValue = null;
    var propertyCategory = 
        layerModel.Owner.DocumentSchema.GetProperty(propertyName);
    if (propertyCategory != null)
    {
      propertyValue = layerModel[propertyCategory];
    }
    return propertyValue;
  }
}

Voir aussi

Autres ressources

Création d'extensions de diagrammes de couche

Historique des modifications

Date

Historique

Motif

Décembre 2010

Mis à jour pour Microsoft Visual Studio 2010 Feature Pack 2.

Améliorations apportées aux informations.