Partilhar via


Como: definir restrições de validação dos modelos UML

Em Visual Studio Ultimate, você pode definir as restrições de validação testam se o modelo que está de acordo com uma condição que você especificar.Por exemplo, você pode definir uma restrição para certificar-se que um usuário não cria um loop de relações de herança.A restrição é chamada quando o usuário tentar abrir ou salvar o modelo, e também pode ser chamada manualmente.Se a restrição falhar, uma mensagem de erro que você defina é adicionada à janela de erro.Você pode armazenar essas restrições em uma extensão de integração de Visual Studio (VSIX) e distribui-las para outros usuários de Visual Studio Ultimate .

Você também pode definir restrições que valida o modelo com recursos externos como bancos de dados.

ObservaçãoObservação

Se você deseja validar o código de programa em um diagrama de camada Adicionar validação personalizada da arquitetura a diagramas de camada, consulte.

Requisitos

Aplicando restrições de validação

As restrições de validação são aplicadas em três casos: quando você salva um modelo; quando você abrir um modelo; quando você validar o modelo de UML e clique no menu de Arquitetura .Em cada caso, somente as restrições que foram definidas para esse caso serão aplicadas, embora geralmente você defina cada restrição para aplicar em mais de um caso.

Erros de validação são reportados na janela de erros de Visual Studio , e você pode clicar duas vezes o erro para selecionar os elementos modelo que estão no erro.

Para obter mais informações sobre como aplicar a validação, consulte Validar um modelo UML.

Definindo uma extensão de validação

Para criar uma extensão de validação para um designer de UML, você deve criar uma classe que define as restrições de validação, e insere a classe em uma extensão de integração do Visual Studio (VSIX).O VSIX atua como um recipiente que possa instalar a restrição.Há dois métodos alternativas de definir uma extensão de validação:

  • Crie uma extensão de validação em seu próprio VSIX usando um modelo de projeto. Este método é o mais rápido.Use se você não desejar combinar as restrições de validação com outros tipos de extensão como comandos de menu, itens personalizados da caixa de ferramentas, ou manipuladores do gesto.Você pode definir várias restrições em uma classe.

  • Crie a classe separada de validação e projetos de VSIX. Use este método se você desejar combinar vários tipos de extensão no mesmo VSIX.Por exemplo, se o comando de menu espera o modelo observe restrições específicas, você pode incorporar-lo no mesmo VSIX que um método de validação.

Para criar uma extensão de validação em seu próprio VSIX

  1. Em a caixa de diálogo de Novo Projeto , em modelando projetos, Extensão de validaçãoselecione.

  2. Abra o arquivo de .cs no novo projeto e modificar a classe para implementar a restrição de validação.

    Para obter mais informações, consulte Implementando a restrição de validação.

    Observação importanteImportante

    Certifique-se de que os arquivos de .cs contêm a seguinte declaração de using :

    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;

  3. Você pode adicionar restrições adicionais definindo novos métodos.Para identificar um método como um método de validação, deve ser etiquetada com os atributos da mesma forma que o método inicial de validação.

  4. Testar suas restrições pressionando F5.Para obter mais informações, consulte Executando validação.

  5. Instalar o comando de menu em outro computador copiar o arquivo bin\*\*.vsix que é compilado pelo projeto.Para obter mais informações, consulte Instalando as restrições de validação.

Quando você adiciona outros arquivos de .cs , você normalmente irá precisar das seguintes declarações de using :

using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
using Microsoft.VisualStudio.Modeling.Validation;
using Microsoft.VisualStudio.Uml.Classes;

Aqui está o procedimento alternativo:

Para criar uma restrição separada de validação em uma biblioteca de classes projeto

  1. Crie um projeto de biblioteca de classes, adicionando um a uma solução existente de VSIX, ou criar uma nova solução.

    1. Em o menu de Arquivo , escolha Novo, Projeto.

    2. Em modelos instalados, expanda Visual C# ou Visual Basic, e na coluna do meio Biblioteca de Classesescolha.

  2. A menos que sua solução já contém um, crie um projeto de VSIX:

    1. Em Gerenciador de Soluções, no menu de atalho da solução, escolha Adicionar, Novo Projeto.

    2. Em modelos instalados, expanda Visual C# ou Visual Basic, então escolha Extensibilidade.Em a coluna do meio, clique em projeto de VSIX.

  3. Defina o projeto de VSIX como o projeto de inicialização de solução.

    • Em o solution Explorer, no menu de atalho do projeto de VSIX escolha Definir como projeto de inicialização.
  4. Em source.extension.vsixmanifest, em Conteúdo, adicione o projeto de biblioteca de classe como um componente de MEF:

    1. Em a guia de metadados , definir um nome para o VSIX.

    2. Em a guia de Destinos instalar , defina o Visual Studio final e superior como destinos.

    3. Em a guia de recursos , escolha Novo, e na caixa de diálogo, defina:

      Tipo = Componente de MEF

      Origem = Um projeto na solução atual

      Projeto = Seu projeto de biblioteca de classe

Para definir a classe de validação

  1. Você não precisa se esse procedimento você criar uma classe de validação com seu próprio VSIX do modelo de projeto de validação.

  2. Em o projeto da classe de validação, adicione referências para os seguintes conjuntos de .NET :

    Microsoft.VisualStudio.Modeling.Sdk.11.0

    Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml

    Microsoft.VisualStudio.Uml.Interfaces

    System.ComponentModel.Composition

  3. Adicionar um arquivo ao projeto de biblioteca de classe que contém o código que é semelhante ao seguinte exemplo.

    • Cada restrição de validação está contida em um método que foi marcado com um atributo específico.o método aceita um parâmetro de um tipo de elemento modelo.Quando a validação é chamado, a estrutura de validação aplicará cada método de validação para cada elemento modelo que está de acordo com o tipo de parâmetro.

    • Você pode colocar esses métodos nas classes e namespaces.Alterá-los a sua preferência.

    using System.Collections.Generic;
    using System.ComponentModel.Composition;
    using System.Linq;
    using Microsoft.VisualStudio.Modeling.Validation;
    using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Uml;
    using Microsoft.VisualStudio.Uml.Classes;
    // You might also need the other Microsoft.VisualStudio.Uml namespaces.
    
    namespace Validation
    {
      public class MyValidationExtensions
      {
        // SAMPLE VALIDATION METHOD.
        // All validation methods have the following attributes.
        [Export(typeof(System.Action<ValidationContext, object>))]
        [ValidationMethod(
           ValidationCategories.Save
         | ValidationCategories.Open
         | ValidationCategories.Menu)]
        public void ValidateClassNames
          (ValidationContext context, 
           // This type determines what elements 
           // will be validated by this method:
           IClass elementToValidate)
        {
          // A validation method should not change the model.
    
          List<string> attributeNames = new List<string>();
          foreach (IProperty attribute in elementToValidate.OwnedAttributes)
          {
            string name = attribute.Name;
            if (!string.IsNullOrEmpty(name) && attributeNames.Contains(name))
            {
              context.LogError(
                string.Format("Duplicate attribute name '{0}' in class {1}", name, elementToValidate.Name),
                "001", elementToValidate);
            }
            attributeNames.Add(name);
          }
    
        }
        // Add more validation methods for different element types.
      }
    }
    

Executando uma restrição de validação

Para fins de teste, executar seus métodos de validação no modo de depuração.

Para testar a restrição de validação

  1. Pressione F5, ou no menu de Depurar , escolha Iniciar Depuração.

    Uma instância de avaliação de Visual Studio .

    Solução de Problemas: se novo Visual Studio não começa:

    • Se você tiver mais de um projeto, certifique-se que o projeto de VSIX é definido como o projeto de inicialização de solução.

    • Em o solution Explorer, no menu de atalho de inicialização ou somente de projeto, escolha Propriedades.Em o editor de propriedades do projeto, selecione a guia de Depurar .Certifique-se de que a cadeia de caracteres no campo de Inicie o programa externo é o nome do caminho completo de Visual Studio, normalmente:

      C:\Program Files\Microsoft Visual Studio 11,0 \ Common7 \ IDE \ devenv.exe

  2. Em Visual Studiode avaliação, abra ou crie um projeto e modelagem, abra ou crie um diagrama modelando.

  3. Para configurar um teste para a restrição de exemplo fornecida na seção anterior:

    1. Abra um diagrama de classe.

    2. Crie uma classe, e adicione dois atributos que têm o mesmo nome.

  4. Em o menu de atalho em qualquer lugar no diagrama, escolha Validar.

  5. Todos os erros no modelo serão relatadas na janela de erros.

  6. Clique duas vezes no relatório de erros.Se os elementos citados no relatório estão visíveis na tela, estarão realçadas.

    Solução de Problemas: Se o comando de Validar não aparece no menu, certifique-se que:

    • O projeto de validação é listado como um componente de MEF na guia de recursos em source.extensions.manifest no projeto de VSIX.

    • Export e atributos de ValidationMethod corretos estão conectados aos métodos de validação.

    • ValidationCategories.Menu é incluído no argumento para o atributo de ValidationMethod , e é composto por outros valores usando o OU (lógico|).

    • Os parâmetros de qualquer Import e atributos de Export são válidos.

Avaliando a restrição

O método de validação deve determinar se a restrição de validação que você deseja aplicar é verdadeira ou falsa.Se verdadeiro, deve não fazer nada.Se falso, deve relatar um erro usando os métodos fornecidos pelo parâmetro de ValidationContext .

ObservaçãoObservação

Os métodos de validação não devem alterar o modelo.Não há nenhuma garantia quando ou a ordem em que as restrições serão executadas.Se você precisa passar informações entre executa sucessivas de um método de validação dentro de uma execução de validação, você pode usar o cache de contexto descrito em Coordenando mais validação.

Por exemplo, se você quiser garantir que cada tipo (a classe, interface, enumeração ou) tem um nome que é pelo menos três caracteres, você pode usar esse método:

public void ValidateTypeName(ValidationContext context, IType type)
{
  if (!string.IsNullOrEmpty(type.Name) && type.Name.Length < 3)
  {
    context.LogError(
      string.Format("Type name {0} is too short", type.Name),
               "001", type);
   }
 }

Consulte Programação com a API de UML para obter informações sobre métodos e dos tipos que você pode usar para navegar e ler o modelo.

Ee329482.collapse_all(pt-br,VS.110).gifSobre os métodos de restrição de validação

Cada restrição de validação é definida por um método da seguinte forma:

[Export(typeof(System.Action<ValidationContext, object>))]
 [ValidationMethod(ValidationCategories.Save 
  | ValidationCategories.Menu 
  | ValidationCategories.Open)]
public void ValidateSomething
  (ValidationContext context, IClassifier elementToValidate)
{...}

Os atributos e parâmetros de cada método de validação são:

[Export(typeof(System.Action <ValidationContext, object>))]

Define o método como uma restrição de validação usando o framework (MEF) gerenciado de extensibilidade.

[ValidationMethod (ValidationCategories.Menu)]

Especifica quando a validação será executada.Use OU bit a bit (|) se você desejar combinar mais de uma opção.

Menu = chamado pelo menu validar.

Save = chamado em salvar o modelo.

Open = chamado em abrir o modelo.Load = invocou salvar no modelo, mas para uma contravenção avisará o usuário que pode não ser possível reabra o modelo.O carregamento também chamado, antes do modelo é analisada.

public void ValidateSomething

(ValidationContext context,

IElement element)

Substitua o parâmetro IElement pelo tipo de elemento a que você deseja que a restrição para aplicar.O método será chamado de restrição em todos os elementos no tipo especificado.

O nome do método são sem importância.

Você pode definir tantas métodos de validação como desejar, com tipos diferentes no segundo parâmetro.Quando a validação é chamada de validação, cada método será chamado cada elemento modelo que está de acordo com o tipo de parâmetro.

Ee329482.collapse_all(pt-br,VS.110).gifErros de validação de relatório

Para criar um relatório de erros, use os métodos fornecidos por ValidationContext:

context.LogError("error string", errorCode, elementsWithError);

  • "error string" aparece na lista de erro de Visual Studio

  • errorCode é uma cadeia de caracteres que deve ser um identificador exclusivo de erro

  • elementsWithError identifica os elementos no modelo.Quando o usuário clica duas vezes no relatório de erros, a forma que representa este elemento será selecionada.

LogError(),LogWarning() e LogMessage() as mensagens em diferentes seções de lista de erros.

Como os métodos de validação são aplicados

A validação é aplicado a cada elemento no modelo, incluindo relacionamentos e partes dos elementos maiores, como atributos de uma classe e de parâmetros de uma operação.

Cada método de validação é aplicado a cada elemento que está de acordo com o tipo no segundo parâmetro.Isso significa que, por exemplo, se você definir um método de validação com um segundo parâmetro de IUseCase e outra com seu supertype IElement, então ambos esses métodos serão aplicados a cada caso de uso no modelo.

A hierarquia de tipos é resumida em Tipos de elemento de modelo.

Você também pode acessar elementos por seguintes relações.Por exemplo, se você fosse definir um método de validação em IClass, você pode fazer loop através das suas propriedades possuídas:

public void ValidateTypeName(ValidationContext context, IClass c)
{
   foreach (IProperty property in c.OwnedAttributes)
   {
       if (property.Name.Length < 3)
       {
            context.LogError(
                 string.Format(
                        "Property name {0} is too short", 
                        property.Name), 
                 "001", property);
        }
   }
}

Ee329482.collapse_all(pt-br,VS.110).gifCriando um método de validação no modelo

Se você quiser garantir que um método de validação seja chamado exatamente uma vez durante cada execução de validação, você pode validar IModel:

using Microsoft.VisualStudio.Uml.AuxiliaryConstructs; ...
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{  foreach (IElement element in model.OwnedElements)
   { ...

Ee329482.collapse_all(pt-br,VS.110).gifValidando formas e diagramas

Os métodos de validação não são invocados nos elementos de exibição tais como diagramas e formas, como o objetivo principal de métodos de validação é validar o modelo.Mas você pode acessar o diagrama atual usando o contexto do diagrama.

Em sua classe de validação, DiagramContext como declarar uma propriedade importado:

using Microsoft.VisualStudio.ArchitectureTools.Extensibility.Presentation; 
...
[Import]
public IDiagramContext DiagramContext { get; set; }

Em um método de validação, você pode usar DiagramContext para acessar o diagrama atual de foco, se houver um:

[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu)]
public void ValidateModel(ValidationContext context, IModel model)
{
  IDiagram focusDiagram = DiagramContext.CurrentDiagram;
  if (focusDiagram != null)
  {
    foreach (IShape<IUseCase> useCaseShape in
              focusDiagram.GetChildShapes<IUseCase>())
    { ...

Para registrar um erro, você deve obter o elemento modelo que representa a forma, porque você não pode passar uma forma a LogError:

       IUseCase useCase = useCaseShape.Element;
       context.LogError(... , usecase);

Ee329482.collapse_all(pt-br,VS.110).gifCoordenando mais validação

Quando a validação é chamada por exemplo, pelo usuário de um menu do diagrama, cada método de validação é aplicado a cada elemento modelo.Isso significa que, em uma única chamada de estrutura de validação, o mesmo método pode ser aplicado várias vezes para diferentes elementos.

Isso representa um problema para as validações que manipulam as relações entre elementos.Por exemplo, você pode escrever uma validação que partisse por exemplo dos exemplos de uso, e passa pelas relações de include para verificar que não houvesse nenhum loop.Mas quando o método é aplicado a cada caso de uso em um modelo que tenha vários links de include , é provável processar repetidamente as mesmas áreas do modelo.

Para evitar essa situação, há um cache de contexto no qual a informação é preservada durante a execução de validação.Você pode usá-las para passar informações entre executa diferentes de métodos de validação.Por exemplo, você pode armazenar uma lista dos elementos que tenham sido manipulados já em esta execução de validação.O cache é criado no início de cada execução de validação, e não pode ser usado para transmitir informações entre diferentes seqüências de validação.

context.SetCacheValue<T> (name, value)

Armazenar um valor

context.TryGetCacheValue<T> (name, out value)

Obter um valor.Retorna true se com êxito.

context.GetValue<T>(name)

Obter um valor.

Context.GetValue<T>()

Obter um valor do tipo especificado.

Instalando e desinstalar uma extensão

Você pode instalar uma extensão de Visual Studio no seu próprio computador e em outros computadores.

Para instalar uma extensão

  1. Em o seu computador, localize o arquivo de .vsix que foi compilado pelo projeto de VSIX.

    1. Em Gerenciador de Soluções, no menu de atalho do projeto de VSIX, escolha Abrir pasta no Windows Explorer.

    2. Localize o arquivo bin\*\YourProject.vsix

  2. Copie o arquivo de .vsix para o computador de destino que você deseja instalar a extensão.Isso pode ser o seu próprio computador ou outro.

    • O computador de destino deve ter uma das edições de Visual Studio que você especificou em source.extension.vsixmanifest.
  3. Em o computador de destino, abra o arquivo de .vsix .

    Instalador de extensão do Visual Studio abre e instala a extensão.

  4. Início ou reinicie Visual Studio.

Para desinstalar uma extensão

  1. Em o menu de Ferramentas , escolha gerenciador de extensão.

  2. Expanda extensões instaladas.

  3. Selecione a extensão, e então escolha Desinstalar.

Raramente, uma extensão defeituosas não carrega e cria um relatório na janela de erro, mas não aparece no gerenciador de extensão.Em esse caso, você pode remover a extensão deletando o arquivo do local onde a seguir %LocalAppData% é normalmente DriveName: UsuáriosNome do Usuário\ \ \ \ AppData local:

%LocalAppData%\Microsoft\VisualStudio\11.0\Extensions

Exemplo

Este exemplo localiza loop no relacionamento de dependência entre elementos.

Validará a salvar e no comando de menu validar.

/// <summary>
/// Verify that there are no loops in the dependency relationsips.
/// In our project, no element should be a dependent of itself.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">Element to start validation from.</param>
[Export(typeof(System.Action<ValidationContext, object>))]
[ValidationMethod(ValidationCategories.Menu 
     | ValidationCategories.Save | ValidationCategories.Open)]
public void NoDependencyLoops(ValidationContext context, INamedElement element)
{
    // The validation framework will call this method
    // for every element in the model. But when we follow
    // the dependencies from one element, we will validate others.
    // So we keep a list of the elements that we don't need to validate again. 
    // The list is kept in the context cache so that it is passed
    // from one execution of this method to another.
    List<INamedElement> alreadySeen = null;
    if (!context.TryGetCacheValue("No dependency loops", out alreadySeen))
    {
       alreadySeen = new List<INamedElement>();
       context.SetCacheValue("No dependency loops", alreadySeen);
    }

    NoDependencyLoops(context, element, 
                new INamedElement[0], alreadySeen);    
}

/// <summary>
/// Log an error if there is any loop in the dependency relationship.
/// </summary>
/// <param name="context">Validation context for logs.</param>
/// <param name="element">The element to be validated.</param>
/// <param name="dependants">Elements we've followed in this recursion.</param>
/// <param name="alreadySeen">Elements that have already been validated.</param>
/// <returns>true if no error was detected</returns>
private bool NoDependencyLoops(ValidationContext context, 
    INamedElement element, INamedElement[] dependants, 
    List<INamedElement> alreadySeen)
{
    if (dependants.Contains(element))
    {
        context.LogError(string.Format("{0} should not depend on itself", element.Name), 
        "Fabrikam.UML.NoGenLoops", // unique code for this error
        dependants.SkipWhile(e => e != element).ToArray()); 
            // highlight elements that are in the loop
        return false;
    }
    INamedElement[] dependantsPlusElement = 
        new INamedElement[dependants.Length + 1];
    dependants.CopyTo(dependantsPlusElement, 0);
    dependantsPlusElement[dependantsPlusElement.Length - 1] = element;

    if (alreadySeen.Contains(element))
    {
        // We have already validated this when we started 
        // from another element during this validation run.
        return true;
    }
    alreadySeen.Add(element);

    foreach (INamedElement supplier in element.GetDependencySuppliers())
    {
        if (!NoDependencyLoops(context, supplier,
             dependantsPlusElement, alreadySeen))
        return false;
    }
    return true;
}

Consulte também

Conceitos

Como: definir e instalar uma extensão de modelagem

Programação com a API de UML