Adicionar validação de arquitetura de personalizada aos diagramas de camada

Em Visual Studio 2010 Ultimate e Visual Studio 2010 Premium, os usuários podem validar o código-fonte em um Visual Studio modelo de projeto em relação uma camada para que eles possam verificar que o código-fonte está de acordo com as dependências em um diagrama de camada. Há um algoritmo de validação padrão, mas este Visual Studio 2010 do feature pack lhe permite definir suas próprias extensões de validação para Visual Studio Ultimate e Visual Studio Premium. Para obter mais informações, consulte Pacotes de funcionalidades de Visual Studio.

Quando o usuário seleciona o Arquitetura validar de comando em um diagrama de camada, o método de validação padrão é invocado, seguido de quaisquer extensões de validação que foram instalados.

ObservaçãoObservação

Validação em um diagrama de camada não é a mesma validação em diagramas UML. Em um diagrama de camada, o principal objetivo é comparar o diagrama com o código de programa em outras partes da solução.

Você pode empacotar sua extensão de validação da camada em um Visual Studio integração extensão (VSIX), que você pode distribuir outros Visual Studio Ultimate os usuários. Você pode colocar o validador em um VSIX por si só, ou você pode combinar-na mesma VSIX como outras extensões. Você deve escrever o código do validador no seu próprio Visual Studio o projeto, não no mesmo projeto como outras extensões.

Requisitos

Para os requisitos e instruções de instalação, consulte Requirements na Criando extensões para diagramas de camada.

Definir um validador de camada em um novo VSIX

O método mais rápido de criar um validador é usar o modelo de projeto. Isso coloca o código e o manifesto VSIX no mesmo projeto.

Para definir uma extensão usando um modelo de projeto

  1. Criar um projeto em uma nova solução, usando o Novo projeto comando o arquivo menu.

  2. No Novo projeto caixa de diálogo, em Projetos de modelagem, selecione Extensão de validação do Designer de camada de.

    O modelo cria um projeto que contém um pequeno exemplo.

  3. Edite o código para definir sua validação. Para obter mais informações, consulte Programação validação.

  4. Para testar a extensão, consulte Validação de camada de depuração.

    ObservaçãoObservação

    O método será chamado apenas em circunstâncias específicas e pontos de interrupção não funcionará automaticamente. Para obter mais informações, consulte Validação de camada de depuração.

  5. Para instalar a extensão na instância principal do Visual Studio, ou em outro computador, localize o .vsix o arquivo em bin\*. Copie-o para o computador onde você deseja instalá-lo e, em seguida, clique duas vezes nele. Para desinstalá-lo, use Extension Manager sobre o Ferramentas menu.

Adicionando um validador de camada para um VSIX separado

Se você deseja criar um VSIX que contém os validadores de camada, comandos e outras extensões, recomendamos que você criar um projeto para definir o VSIX e projetos separados para os manipuladores. Para obter informações sobre outros tipos de extensão de modelagem, consulte Diagramas e modelos UML estendendo.

Adicionar validação de camada para um VSIX separado

  1. Criar uma biblioteca de classe de projeto em um novo ou existente Visual Studio Ultimate solução. No Novo projeto caixa de diálogo, clique em C# Visual e, em seguida, clique em Biblioteca de classe. Este projeto contém a classe de validação da camada.

  2. Identificar ou criar um projeto VSIX em sua solução. Um projeto VSIX contém um arquivo chamado source.extension.vsixmanifest. Se você tiver que adicionar um projeto VSIX, execute estas etapas:

    1. No Novo projeto diálogo caixa, expanda Visual C#, em seguida, clique em extensibilidadee em seguida, clique em VSIX projeto.

    2. No Solution Explorer, clique com o botão direito no projeto VSIX e clique em Set as Startup Project.

    3. Clique em Selecione edições e certifique-se de que Visual Studio Ultimate é verificada.

  3. Em source.extension.vsixmanifest, em conteúdo, adicione o projeto de validação de camada como um componente MEF:

    1. Clique em Adicionar conteúdo.

    2. Em Selecione um tipo de conteúdo, selecione MEF componente.

    3. Em Selecionar uma fonte de, clique em projeto e selecione o nome do seu projeto de manipulador de comando ou o gesto.

    4. Salve o arquivo.

  4. Adicione o projeto de validação de camada como uma extensão personalizada:

    1. Clique em Adicionar conteúdo.

    2. Em Selecione um tipo de conteúdo, selecione Tipo de extensão personalizada

    3. Em tipo de, digite Microsoft.VisualStudio.ArchitectureTools.Layer.Validator

    4. Em Selecionar uma fonte de, clique em projeto e selecione o nome do seu projeto de biblioteca de classe de validação.

  5. Em referências clique em Adicionar referência de e selecione o tempo de execução para este pacote de recursos.

  6. Retornar ao projeto de validação da camada e, em seguida, adicione as seguintes referências de projeto:

    Referência

    O que isso permite que você faça

    Se você tiver Visual Studio visualização de 2010 e modelagem Feature Pack instalado:

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization e Runtime\1.0\Microsoft.VisualStudio.GraphModel.dll do pacote de recurso de modelagem.

    Se você tiver Visual Studio 2010 recurso Pack 2 instalado:

    10.0\Common7\IDE\Extensions\Microsoft\Visualization de Visual Studio de …\Microsoft e Runtime\1.0\Microsoft.VisualStudio.GraphModel.dll do pacote de recurso de modelagem.

    Ler o gráfico de arquitetura

    Se você tiver Visual Studio visualização de 2010 e modelagem Feature Pack instalado:

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization e Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll do pacote de recurso de modelagem.

    Se você tiver Visual Studio 2010 recurso Pack 2 instalado:

    Visualização de 10.0\Common7\IDE\Extensions\Microsoft\ de Visual Studio de …\Microsoft e Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.CodeSchema.dll do pacote de recurso de modelagem.

    Leia que o DOM do código associado a camadas

    Se você tiver Visual Studio visualização de 2010 e modelagem Feature Pack instalado:

    %LocalAppData%\Microsoft\VisualStudio\10.0\Extensions\Microsoft\Visualization e Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll do pacote de recurso de modelagem.

    Se você tiver Visual Studio 2010 recurso Pack 2 instalado:

    10.0\Common7\IDE\Extensions\Microsoft\Visualization de Visual Studio de …\Microsoft e Runtime\1.0\Microsoft.VisualStudio.ArchitectureTools.Extensibility.Layer.dll do pacote de recurso de modelagem.

    Leia o modelo de camada

    Microsoft.VisualStudio.UML.interfaces

    Leia o modelo de camada

    Microsoft.VisualStudio.ArchitectureTools.Extensibility

    Ler e atualizar as formas e diagramas.

    System.ComponentModel.Composition

    Definir o componente de validação usando o Managed Extensibility Framework (MEF)

    Microsoft.VisualStudio.Modeling.SDK.10.0

    Definir as extensões de modelagem

    ObservaçãoObservação

    Costuma ser % LocalAppData % Nome_da_unidade: \Users\nome de usuário\AppData\Local. No Windows XP ou Windows 2003, use % AppData % em vez de % LocalAppData %.

  7. Edite o arquivo de classe no C# classe projeto da biblioteca para conter o código de sua validação. Para obter mais informações, consulte Programação validação.

  8. Para testar a extensão, consulte Validação de camada de depuração.

    ObservaçãoObservação

    O método será chamado apenas em circunstâncias específicas e pontos de interrupção não funcionará automaticamente. Para obter mais informações, consulte Validação de camada de depuração.

  9. Para instalar o VSIX na instância principal do Visual Studio, ou em outro computador, localize o .vsix de arquivo na bin o diretório do projeto VSIX. Copie-o para o computador onde você deseja instalar o VSIX. Clique duas vezes no arquivo VSIX no Windows Explorer.

    Para desinstalá-lo, use Extension Manager sobre o Ferramentas menu.

Validação de programação

Para definir uma extensão de validação de camada, você pode definir uma classe que tem as seguintes características:

  • O formulário geral da declaração é o seguinte:

      [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 você descobrir um erro, relate-o usando LogValidationError().

Quando o usuário chama o Arquitetura validar comando de menu, o sistema de runtime da camada analisa as camadas e os artefatos para produzir um gráfico. O gráfico tem quatro partes:

  • Os modelos de camada da Visual Studio solução que são representados como nós e os links no gráfico.

  • O código, os itens de projeto e outros artefatos que são definidos na solução e são representados como nós e links que representam as dependências descobertas pelo processo de análise.

  • Links de nós de camada para os nós de artefato do código.

  • Nós que representam os erros descobertos pelo validador.

Quando o gráfico foi construído, o método de validação padrão é chamado. Quando isso for concluído, quaisquer métodos de validação de extensão instalados são chamados na ordem não especificado. O gráfico é passado para cada ValidateArchitecture método, que pode verificar o gráfico e relatório de erros que ele localiza.

ObservaçãoObservação

Isso não é o mesmo que o processo de validação é aplicado a diagramas UML, e não é o mesmo que o processo de validação pode ser usado em linguagens específicas de domínio.

Métodos de validação não devem alterar o modelo de camada ou o código que está sendo validado.

O modelo de gráfico é definido em Microsoft.VisualStudio.GraphModel. Suas classes de entidade são Node e Link.

Cada nó e cada Link tem uma ou mais categorias que especificam o tipo de elemento ou o relacionamento que ele representa. Os nós de um gráfico típico têm as seguintes categorias:

  • DSL.LayerModel

  • DSL.Layer

  • DSL.Reference

  • CodeSchema_Type

  • CodeSchema_Namespace

  • CodeSchema_Type

  • CodeSchema_Method

  • CodeSchema_Field

  • CodeSchema_Property

Links de camadas para elementos do código tenham a categoria "Representa".

O código a seguir é um exemplo típico de uma extensão de validação da arquitetura. Ele verifica se todos os tipos declarados no código da solução é referenciado pelo menos uma vez pelo modelo de camada. O usuário pode controlar se essa validação deve ser executada em cada modelo de camada, definindo uma propriedade personalizada Boolean do modelo.

Se um erro for encontrado, LogValidationError é chamado.

Validação de depuração.

Para depurar a sua extensão de validação de camada, pressione CTRL + F5. Uma instância experimental do Visual Studio será aberta. Neste exemplo, abrir ou criar um modelo de camada. Este modelo deve ser associado ao código e deve ter pelo menos uma dependência.

Teste com uma solução que contém dependências

Validação não é executada, a menos que as seguintes características estão presentes:

  • Há pelo menos um link de dependência no diagrama de camada.

  • Há camadas no modelo que estão associadas a elementos de código.

Na primeira vez que você iniciar uma instância experimental do Visual Studio para testar sua extensão de validação, abrir ou criar uma solução que tem essas características.

Execução limpar solução antes de validar a arquitetura

Sempre que você atualizar seu código de validação, use o Limpar solução comando o Build menu na solução experimental, antes de testar o comando de validar. Isso é necessário porque são armazenados em cache os resultados da validação. Se você não atualizou o diagrama de camada de teste ou em seu código, os métodos de validação não serão executados.

Iniciar o depurador explicitamente

Validação é executada em um processo separado. Portanto, que os pontos de interrupção no seu método de validação não serão acionados. Você deve anexar o depurador ao processo explicitamente quando iniciou a validação.

Para anexar o depurador ao processo de validação, inserir uma chamada a System.Diagnostics.Debugger.Launch() no início do seu método de validação. Quando for exibida a caixa de diálogo de depuração, selecione a instância principal do Visual Studio.

Como alternativa, você pode inserir uma chamada para System.Windows.Forms.MessageBox.Show(). Quando a caixa de mensagem for exibida, vá para a instância principal do Visual Studio e o Debug menu clique Attach to Process. Selecione o processo que é denominado Graphcmd.exe.

Sempre iniciar a instância experimental pressionando CTRL + F5 (Iniciar sem depuração).

Implantando uma extensão de validação

Para instalar a extensão de validação em um computador no qual Visual Studio Ultimate ou Visual Studio Premium é instalado, abra o arquivo VSIX no computador de destino. Para instalar em um computador no qual Team Foundation Build é instalado, você deve extrair manualmente o conteúdo VSIX em uma pasta de extensões. Para obter mais informações, consulte A implantação de uma camada de extensão de modelagem..

Exemplo

O exemplo a seguir ilustra uma extensão de validação da camada.

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

Consulte também

Outros recursos

Criando extensões para diagramas de camada

Histórico de alterações

Date

History

Motivo

Dezembro de 2010

Atualizado para Visual Studio 2010 Feature Pack 2.

Aprimoramento de informações.