Condividi tramite


Aggiunta di strumenti di convalida architettura personalizzati a diagrammi livelli

In Visual Studio 2010 Ultimate e Visual Studio 2010 Premium, gli utenti possono convalidare il codice sorgente in un progetto di Visual Studio in base a un modello di livello per verificarne la conformità alle dipendenze di un diagramma livello. Per quanto sia disponibile a tale scopo un algoritmo di convalida standard, questo Feature Pack di Visual Studio 2010 consente di definire estensioni della convalida personalizzate per Visual Studio Ultimate e Visual Studio Premium. Per ulteriori informazioni, vedere Feature Pack di Visual Studio.

Quando l'utente seleziona il comando Convalida architettura in un diagramma livello, viene richiamato il metodo di convalida standard, seguito dalle estensioni della convalida installate.

Nota

La convalida in un diagramma livello non corrisponde alla convalida nei diagrammi UML. In un diagramma livello, lo scopo principale è confrontare il diagramma con il codice programma di altre parti della soluzione.

È possibile comprimere l'estensione di convalida dei livelli personalizzata in un progetto VSIX (Visual Studio Integration Extension) da distribuire ad altri utenti di Visual Studio Ultimate. Il validator può essere incluso in un progetto VSIX separatamente o insieme ad altre estensioni. È opportuno scrivere il codice del validator in un progetto di Visual Studio specifico anziché insieme ad altre estensioni.

Requisiti

Per i requisiti e le istruzioni relative all'installazione, vedere Requisiti in Creazione di estensioni per diagrammi livelli.

Definizione di un validator dei livelli in un nuovo progetto VSIX

Il metodo più rapido per la creazione di un validator consiste nell'utilizzare il modello di progetto. Tale approccio comporta l'inclusione del codice e del manifesto VSIX nello stesso progetto.

Per definire un'estensione tramite un modello di progetto

  1. Creare un progetto in una nuova soluzione utilizzando il comando Nuovo progetto del menu File.

  2. Nella finestra di dialogo Nuovo progetto, sotto Progetti di modello fare clic su Estensione di convalida Progettazione livelli.

    In base al modello viene creato un progetto contenente un piccolo esempio.

  3. Modificare il codice per definire la convalida. Per ulteriori informazioni, vedere Programmazione della convalida dei livelli.

  4. Per eseguire il test dell'estensione, vedere Debug della convalida dei livelli.

    Nota

    Il metodo verrà chiamato solo in specifiche circostanze e i punti di interruzione non funzioneranno in modo automatico. Per ulteriori informazioni, vedere Debug della convalida dei livelli.

  5. Per installare l'estensione nell'istanza principale di Visual Studio o in un altro computer, individuare il file .vsix in bin\*. Copiarlo nel computer in cui si desidera installare l'estensione, quindi fare doppio clic su di esso. Per disinstallare l'estensione, utilizzare Gestione estensioni nel menu Strumenti.

Aggiunta di un validator dei livelli a un progetto VSIX distinto

Se si desidera creare un progetto VSIX contenente validator dei livelli, comandi e altre estensioni, si consiglia di creare un progetto per la definizione dell'estensione VSIX e progetti distinti per i gestori. Per informazioni su altri tipi di estensioni di modello, vedere Estensione di modelli e diagrammi UML.

Per aggiungere la convalida dei livelli a un progetto VSIX distinto

  1. Creare un progetto Libreria di classi in una nuova soluzione di Visual Studio Ultimate o in una esistente. Nella finestra di dialogo Nuovo progetto fare clic su Visual C#, quindi su Libreria di classi. Il progetto conterrà la classe per la convalida dei livelli.

  2. Identificare o creare un progetto VSIX nella soluzione. Un progetto VSIX contiene un file denominato source.extension.vsixmanifest. Se è necessario aggiungere un progetto VSIX, attenersi alla seguente procedura:

    1. Nella finestra di dialogo Nuovo progetto espandere Visual C#, fare clic su Extensibility, quindi su Progetto VSIX.

    2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto VSIX e scegliere Imposta come progetto di avvio.

    3. Fare clic su Seleziona versioni e assicurarsi che sia selezionato Visual Studio Ultimate.

  3. In source.extension.vsixmanifest, sotto Contenuto, aggiungere il progetto di convalida dei livelli come componente MEF:

    1. Fare clic su Aggiungi contenuto.

    2. In Seleziona un tipo di contenuto selezionare Componente MEF.

    3. In Selezionare un'origine fare clic su Progetto e selezionare il nome del progetto di gestore comandi o movimenti.

    4. Salvare il file.

  4. Aggiungere il progetto di convalida dei livelli come estensione personalizzata:

    1. Fare clic su Aggiungi contenuto.

    2. In Seleziona un tipo di contenuto selezionare Tipo di estensione personalizzata

    3. In Tipo immettere Microsoft.VisualStudio.ArchitectureTools.Layer.Validator

    4. In Selezionare un'origine fare clic su Progetto e selezionare il nome del progetto Libreria di classi di convalida.

  5. In Riferimenti fare clic su Aggiungi riferimento e selezionare il runtime per questo Feature Pack.

  6. Tornare al progetto di convalida dei livelli e aggiungere i riferimenti al progetto seguenti:

    Riferimento

    Operazioni consentite

    Se è installato il Feature Pack di visualizzazione e modellazione di Microsoft Visual Studio 2010:

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

    Se è installato Visual Studio 2010 Feature Pack 2:

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

    Leggere il grafico dell'architettura.

    Se è installato il Feature Pack di visualizzazione e modellazione di Microsoft Visual Studio 2010:

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

    Se è installato Visual Studio 2010 Feature Pack 2:

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

    Leggere il modello codeDOM associato ai livelli.

    Se è installato il Feature Pack di visualizzazione e modellazione di Microsoft Visual Studio 2010:

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

    Se è installato Visual Studio 2010 Feature Pack 2:

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

    Leggere il modello di livello.

    Microsoft.VisualStudio.Uml.Interfaces

    Leggere il modello di livello.

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Leggere e aggiornare forme e diagrammi.

    System.ComponentModel.Composition

    Definire il componente di convalida mediante Managed Extensibility Framework (MEF).

    Microsoft.VisualStudio.Modeling.Sdk.10.0

    Definire le estensioni di modello.

    Nota

    %LocalAppData% corrisponde in genere a NomeUnità:\Users\NomeUtente\AppData\Local. In Windows XP e Windows 2003, utilizzare %AppData% anziché %LocalAppData%.

  7. Modificare il file della classe nel progetto Libreria di classi C# per includervi il codice per la convalida. Per ulteriori informazioni, vedere Programmazione della convalida dei livelli.

  8. Per eseguire il test dell'estensione, vedere Debug della convalida dei livelli.

    Nota

    Il metodo verrà chiamato solo in specifiche circostanze e i punti di interruzione non funzioneranno in modo automatico. Per ulteriori informazioni, vedere Debug della convalida dei livelli.

  9. Per installare l'estensione VSIX nell'istanza principale di Visual Studio o in un altro computer, individuare il file .vsix nella directory bin del progetto VSIX. Copiarlo nel computer in cui si desidera installare l'estensione VSIX. In Esplora risorse fare doppio clic sul file VSIX.

    Per disinstallare l'estensione, utilizzare Gestione estensioni nel menu Strumenti.

Programmazione della convalida dei livelli

Per definire un'estensione di convalida dei livelli, è necessario definire una classe con le caratteristiche seguenti:

  • Il formato generico della dichiarazione è il seguente:

      [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);
        }
    
  • Quando si individua un errore, è possibile segnalarlo tramite LogValidationError().

Quando l'utente richiama il comando di menu Convalida architettura, il sistema di runtime dei livelli analizza i livelli e i relativi elementi per generare un grafico. Il grafico è costituito da quattro parti:

  • I modelli di livello della soluzione di Visual Studio, rappresentati come nodi e collegamenti nel grafico.

  • Il codice, gli elementi di progetto e gli altri elementi definiti nella soluzione e rappresentati come nodi e collegamenti che rappresentano le dipendenze individuate dal processo di analisi.

  • I collegamenti dai nodi di livello ai nodi di elementi di codice.

  • I nodi che rappresentano errori individuati dal validator.

Una volta generato il grafico, viene chiamato il metodo di convalida standard. Al termine dell'operazione, vengono chiamati in ordine non specificato i metodi di convalida delle eventuali estensioni installate. Il grafico viene passato a ciascun metodo ValidateArchitecture, che può analizzarlo e segnalare gli eventuali errori rilevati.

Nota

Tale processo di convalida non corrisponde a quello applicato ai diagrammi UML né al processo di convalida che può essere utilizzato nei linguaggi specifici di dominio.

I metodi di convalida non devono modificare il modello di livello o il codice da convalidare.

Il modello del grafico è definito in Microsoft.VisualStudio.GraphModel. Le relative classi principali sono Node e Link.

Ogni classe Node e ogni classe Link dispongono di una o più categorie che specificano il tipo di elemento o di relazione che la classe rappresenta. I nodi di un tipico grafico dispongono delle categorie seguenti:

  • Dsl.LayerModel

  • Dsl.Layer

  • Dsl.Reference

  • CodeSchema_Type

  • CodeSchema_Namespace

  • CodeSchema_Type

  • CodeSchema_Method

  • CodeSchema_Field

  • CodeSchema_Property

I collegamenti dai livelli agli elementi nel codice dispongono della categoria "Rappresenta."

Il codice seguente è un tipico esempio di estensione di convalida dell'architettura. Verifica che a ogni tipo dichiarato nel codice della soluzione sia fatto riferimento almeno una volta dal modello di livello. L'utente può controllare se questa convalida deve essere eseguita su ogni modello di livello impostando una proprietà personalizzata booleana del modello.

Se viene rilevato un errore, viene chiamato LogValidationError.

Debug della convalida dei livelli

Per eseguire il debug dell'estensione di convalida dei livelli, premere CTRL+F5. Verrà aperta un'istanza sperimentale di Visual Studio. In tale istanza, aprire o creare un modello di livello. Il modello deve essere associato a codice e deve disporre di almeno una dipendenza.

Esecuzione del test di una soluzione contenente dipendenze

La convalida viene eseguita solo in presenza delle seguenti caratteristiche:

  • Esiste almeno un collegamento di dipendenza nel diagramma livello.

  • Il modello contiene livelli associati a elementi di codice.

Quando si avvia per la prima volta un'istanza sperimentale di Visual Studio per eseguire il test dell'estensione di convalida, aprire o creare una soluzione che dispone delle caratteristiche menzionate.

Esecuzione di Pulisci soluzione prima di Convalida architettura

Quando si aggiorna il codice di convalida, utilizzare il comando Pulisci soluzione del menu Compila nella soluzione sperimentale prima di eseguire il test del comando Convalida. Tale approccio si rende necessario in quanto i risultati di convalida vengono memorizzati nella cache. Se non si è aggiornato il diagramma livello di test o il relativo codice, i metodi di convalida non verranno eseguiti.

Avvio esplicito del debugger

La convalida viene eseguita in un processo distinto. Pertanto, i relativi punti di interruzione nel metodo di convalida non verranno attivati. È necessario connettere in modo esplicito il debugger al processo quando la convalida è stata avviata.

Per connettere il debugger al processo di convalida, inserire una chiamata a System.Diagnostics.Debugger.Launch() all'inizio del metodo di convalida. Quando viene visualizzata la finestra di dialogo di debug, selezionare l'istanza principale di Visual Studio.

In alternativa, è possibile inserire una chiamata a System.Windows.Forms.MessageBox.Show(). Quando viene visualizzata la finestra di messaggio, passare all'istanza principale di Visual Studio e scegliere Connetti a processo dal menu Debug. Selezionare il processo denominato Graphcmd.exe.

Avviare sempre l'istanza sperimentale premendo CTRL+F5 (Avvia senza eseguire debug).

Distribuzione di un'estensione di convalida

Per installare l'estensione di convalida in un computer in cui è installato Visual Studio Ultimate o Visual Studio Premium, aprire il file VSIX sul computer di destinazione. Per installarla in un computer in cui è installato Team Foundation Build, è necessario estrarre manualmente il contenuto del file VSIX in una cartella Extensions. Per ulteriori informazioni, vedere Distribuzione di un'estensione di modellazione di livello.

Esempio

Nell'esempio seguente viene illustrata un'estensione di convalida dei livelli.

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;
  }
}

Vedere anche

Altre risorse

Creazione di estensioni per diagrammi livelli

Cronologia delle modifiche

Data

Cronologia

Motivo

Dicembre 2010

Contenuto aggiornato per Visual Studio 2010 Feature Pack 2.

Miglioramento delle informazioni.