Compartilhar via


Introdução à Linguagem Específica de Domínio

Este tópico explica os conceitos básicos na definição e no uso de uma DSL (linguagem específica de domínio) criada com o SDK de Modelagem do Visual Studio.

Observação

O SDK de Transformação de Modelo de Texto e o SDK de Modelagem do Visual Studio são instalados automaticamente, quando você instala os recursos específicos do Visual Studio. Para obter mais detalhes, consulte esta postagem no blog.

Se você é novo em DSLs, recomendamos que trabalhe com o DSL Tools Lab, que pode ser encontrado neste site: SDK de Visualização e Modelagem

O que você pode fazer com uma Linguagem Específica de Domínio?

Uma linguagem específica de domínio é uma notação, geralmente gráfica, criada para ser usada para uma finalidade específica. Por outro lado, linguagens como a UML são de uso geral. Em uma DSL, você pode definir os tipos de elemento de modelo e as respectivas relações e como são apresentados na tela.

Ao criar uma DSL, você pode distribuí-la como parte de um pacote VSIX (Extensão de Integração do Visual Studio). Os usuários trabalham com a DSL no Visual Studio:

Gerenciador, caixa de ferramentas e diagrama de árvore genealógica

A notação é apenas parte de uma DSL. Juntamente com a notação, seu pacote VSIX inclui ferramentas que os usuários podem aplicar para ajudar a editar e gerar materiais provenientes dos modelos.

Uma das principais aplicações das DSLs é gerar código de programa, arquivos de configuração e outros artefatos. Especialmente em grandes projetos e linhas de produtos, onde muitas variantes de um produto serão criadas, gerar muitos dos aspectos variáveis das DSLs pode aumentar bastante a confiabilidade e fornecer uma resposta muito rápida às mudanças nos requisitos.

O restante dessa visão geral é um passo a passo que apresenta as operações básicas de criação e uso de uma linguagem específica de domínio no Visual Studio.

Pré-requisitos

Para definir uma DSL, é necessário ter instalados os seguintes componentes:

Componente Link
Visual Studio http://go.microsoft.com/fwlink/?LinkId=185579
SDK do Visual Studio https://go.microsoft.com/fwlink/?linkid=2166172
SDK de Modelagem do Visual Studio

Observação

O componente Transformação de Modelo de Texto é instalado automaticamente como parte da carga de trabalho de Desenvolvimento de extensões do Visual Studio. Você também pode instalá-lo na guia Componentes individuais do Instalador do Visual Studio, na categoria SDKs, bibliotecas e estruturas. Instale o componente SDK de Modelagem na guia Componentes individuais.

Criar uma Solução DSL

Para criar uma nova linguagem específica de domínio, crie uma nova solução do Visual Studio usando o modelo de projeto de Linguagem Específica de Domínio.

  1. No menu Arquivo , aponte para Novoe clique em Projeto.

  2. Em Tipos de projeto, expanda o nó Outros Tipos de Projeto e clique em Extensibilidade.

  3. Clique em Designer de Linguagem Específica de Domínio.

    Caixa de diálogo Criar DSL

  4. Na caixa Nome, digite FamilyTree. Clique em OK.

    O Assistente de Linguagem Específica de Domínio será aberto e exibirá uma lista de soluções DSL do modelo.

    Clique em cada modelo para ver uma descrição.

    Os modelos são pontos de partida úteis. Cada um deles fornece uma DSL de trabalho completa, que você pode editar para atender às suas necessidades. Normalmente, você escolhe o modelo mais próximo do que deseja criar.

  5. Para este passo a passo, escolha o modelo de Linguagem Mínima.

  6. Insira uma extensão de nome de arquivo para sua DSL na página do assistente apropriada. Essa é a extensão que será usada pelos arquivos que contêm as instâncias de sua DSL.

    • Escolha uma extensão que não esteja associada a um aplicativo no seu computador ou nos computadores em que você deseja instalar a DSL. Por exemplo, docx e htm são extensões de nomes de arquivos inaceitáveis.

    • O assistente o avisará se a extensão inserida está sendo usada como uma DSL. Considere usar uma extensão de nome de arquivo diferente. Também é possível redefinir a instância Experimental do SDK do Visual Studio para limpar os designers experimentais antigos. No menu Iniciar do Windows, digite redefinir o Visual Studio e, em seguida, execute o comando Redefinir a Instância Experimental do Microsoft Visual Studio correspondente à sua versão do Visual Studio.

  7. Inspecione as outras páginas e clique em Concluir.

    Uma solução é gerada contendo dois projetos. Eles são chamados de Dsl e DslPackage. Um arquivo de diagrama será aberto com o nome DslDefinition.dsl.

    Observação

    A maior parte do código que você pode ver nas pastas dos dois projetos é gerada a partir do DslDefinition.dsl. Por esse motivo, a maioria das modificações na sua DSL são feitas neste arquivo.

A interface do usuário agora se assemelha à imagem a seguir.

designer de dsl

Essa solução define uma linguagem específica de domínio. Para obter mais informações, confira Visão geral da interface do usuário das Ferramentas de Linguagem Específica de Domínio.

As partes importantes da solução DSL

Observe os seguintes aspectos da nova solução:

  • Dsl\DslDefinition.dsl Este é o arquivo que você vê ao criar uma solução DSL. Quase todo o código na solução é gerado a partir desse arquivo e a maioria das alterações feitas em uma definição de DSL são feitas aqui. Para obter mais informações, confira Como trabalhar com o diagrama de definição de DSL.

  • Projeto DSL Este projeto contém o código que define o idioma específico de domínio.

  • Projeto DslPackage Este projeto contém o código que permite que as instâncias da DSL sejam abertas e editadas no Visual Studio.

Como executar a DSL

Você pode executar a solução DSL assim que for criada. Posteriormente, você pode modificar a definição de DSL gradativamente, executando a solução novamente após cada alteração.

Para experimentar com a DSL

  1. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções. Isso regenera a maior parte do código-fonte do DslDefinition.dsl.

    Observação

    Sempre que você alterar o DslDefinition.dsl, clique em Transformar Todos os Modelos, antes de recompilar a solução. Você pode automatizar esta etapa. Para obter mais informações, confira Como automatizar a transformação de todos os modelos.

  2. Pressione F5 ou, no menu Depurar, clique em Iniciar Depuração.

    A DSL compila e é instalada na instância experimental do Visual Studio.

    Uma instância experimental do Visual Studio é iniciada. A instância experimental usa as configurações de uma subárvore separada do registro, em que as extensões do Visual Studio são registradas para fins de depuração. As instâncias normais do Visual Studio não têm acesso a extensões registradas lá.

  3. Na instância experimental do Visual Studio, abra o arquivo de modelo chamado Teste no Gerenciador de Soluções.

    - ou -

    Clique com o botão direito do mouse na solução, aponte para Adicionar e escolha Item. Na caixa de diálogo Adicionar Item, selecione o tipo de arquivo da DSL.

    O arquivo de modelo será aberto como diagrama em branco.

    A caixa de ferramentas será aberta e exibirá as ferramentas apropriadas para o tipo de diagrama.

  4. Use as ferramentas para criar formas e conectores no diagrama.

    1. Para criar formas, arraste a partir da ferramenta Forma de Exemplo para o diagrama.

    2. Para conectar duas formas, clique na ferramenta Conector de Exemplo, clique na primeira forma e clique na segunda forma.

  5. Clique nos rótulos das formas para alterá-los.

Seu Visual Studio experimental será semelhante ao exemplo a seguir:

Árvore de exemplo de linguagem específica de domínio no Visual Studio

O conteúdo de um modelo

O conteúdo de um arquivo que é uma instância de uma DSL é chamado de modelo. O modelo contém elementos de modelo e links entre os elementos. A definição de DSL especifica quais tipos de elementos de modelo e links podem existir no modelo. Por exemplo, em uma DSL criada a partir do modelo Linguagem Mínima, há um tipo de elemento de modelo e um tipo de link.

A definição de DSL pode especificar como o modelo será exibido em um diagrama. Você pode escolher entre diversos estilos de formas e conectores. Você pode especificar que algumas formas sejam exibidas dentro de outras formas.

Você pode exibir um modelo como uma árvore no modo de exibição do Explorer, enquanto edita um modelo. À medida que você adiciona formas ao diagrama, os elementos de modelo também são exibidos no Explorer. O Explorer pode ser usado mesmo que não haja diagrama.

Se você não conseguir ver o Explorer na instância de depuração do Visual Studio, no menu Exibir, aponte para Outras janelas e clique em <Sua Linguagem> Explorer.

A API da sua DSL

Sua DSL gera uma API que permite ler e atualizar os modelos que são instâncias da DSL. Uma aplicação da API é gerar arquivos de texto de um modelo. Para saber mais, confira Geração de código em tempo de design usando modelos de texto T4.

Na solução de Depuração, abra os arquivos de modelo com a extensão ".tt". Esses exemplos demonstram como você pode gerar texto a partir de modelos e permitem testar a API da sua DSL. Um dos exemplos é gravado no Visual Basic e o outro no Visual C#.

Em cada arquivo de modelo encontra-se o arquivo que ele gera. Expanda o arquivo de modelo em Gerenciador de Soluções e abra o arquivo gerado.

O arquivo de modelo contém um pequeno segmento de código que lista todos os elementos no modelo.

O arquivo gerado contém o resultado.

Ao alterar um arquivo de modelo, você verá as alterações correspondentes nos arquivos gerados depois de regenerar os arquivos.

Para regenerar os arquivos de texto depois de alterar o arquivo de modelo

  1. Na instância experimental do Visual Studio, salve o arquivo de modelo.

  2. Verifique se o parâmetro de nome em cada arquivo .tt se refere ao arquivo de modelo que você está usando para experimentos. Salve o arquivo .tt.

  3. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções.

    - ou -

    Clique com o botão direito do mouse nos modelos que você deseja regenerar e clique em Executar Ferramenta Personalizada.

Você pode adicionar qualquer número de arquivos de modelo de texto a um projeto. Cada modelo gera um arquivo de resultado.

Observação

Quando você alterar a definição de DSL, o código de modelo de texto de exemplo não funcionará, a menos que você a atualize.

Para obter mais informações, confira Como gerar código a partir de uma Linguagem Específica de Domínio e Como gravar código para personalizar uma Linguagem Específica de Domínio.

Personalizando a DSL

Quando você quiser modificar a definição de DSL, feche a instância experimental e atualize a definição na instância principal do Visual Studio.

Observação

Depois de modificar a definição de DSL, você pode perder informações nos modelos de teste criados ao usar versões anteriores. Por exemplo, a solução de depuração contém um arquivo chamado Exemplo, que contém algumas formas e conectores. Depois que você começar a desenvolver sua definição de DSL, eles não ficarão visíveis e serão perdidos quando você salvar o arquivo.

Você pode criar uma ampla gama de extensões para sua DSL. Os exemplos a seguir mostram as possibilidades.

Após cada alteração, salve a definição de DSL, clique em Transformar Todos os Modelos em Gerenciador de Soluções e pressione F5 para experimentar a DSL alterada.

Renomear os tipos e as ferramentas

Renomeie as classes de domínio e as relações existentes. Por exemplo, a partir de uma Definição de DSL criada com o modelo de Linguagem Mínima, você pode executar as seguintes operações de renomeação para fazer com que a DSL represente árvores genealógicas.

Para renomear as classes de domínio, relações e ferramentas

  1. No diagrama DslDefinition, renomeie ExampleModel como FamilyTreeModel, ExampleElement como Pessoa, Destinos como Pais e Origens como Filho. Você pode clicar em cada rótulo para alterá-lo.

    Diagrama de Definição de DSL – modelo de árvore genealógica

  2. Renomeie as ferramentas de elemento e conector.

    1. Abra a janela do Gerenciador de DSL clicando na guia em Gerenciador de Soluções. Se não for possível vê-la, no menu Exibir, aponte para Outras Janelas e clique em Gerenciador de DSL. O Gerenciador de DSL só fica visível quando o diagrama de Definição de DSL é a janela ativa.

    2. Abra a janela Propriedades e posicione-a de modo que você possa ver o Gerenciador de DSL e as Propriedades ao mesmo tempo.

    3. No Gerenciador de DSL, expanda Editor, Guias da Caixa de Ferramentas, <sua DSL> e Ferramentas.

    4. Clique em ExampleElement. Esse é o item da caixa de ferramentas usado para criar elementos.

    5. Na janela Propriedades, altere a propriedade Nome para Pessoa.

      Observe que a propriedade Legenda também será alterada.

    6. Da mesma maneira, altere o nome da ferramenta ExampleConnector para ParentLink. Altere a propriedade Legenda para que ela não seja uma cópia da propriedade Name. Por exemplo, insira Link Pai.

  3. Recompile a DSL.

    1. Salve o arquivo de definição de DSL.

    2. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções

    3. Pressione F5. Aguarde até que a instância experimental do Visual Studio seja exibida.

  4. Na solução de Depuração na instância experimental do Visual Studio, abra um arquivo de modelo de teste. Arraste os elementos para ele a partir da caixa de ferramentas. Observe que as legendas da ferramenta e os nomes de tipo no Gerenciador de DSL foram alterados.

  5. Salve o arquivo de modelo.

  6. Abra um arquivo .tt e substitua as ocorrências do tipo antigo e os nomes de propriedade pelos novos nomes.

  7. Verifique se o nome do arquivo especificado no arquivo .tt especifica seu modelo de teste.

  8. Salve o arquivo .tt. Abra o arquivo gerado para ver o resultado da execução do código no arquivo .tt. Verifique se está correto.

Adicionar propriedades de domínio a classes

Adicione propriedades a uma classe de domínio, por exemplo, para representar os anos de nascimento e óbito de uma pessoa.

Para tornar as novas propriedades visíveis no diagrama, você deve adicionar decoradores à forma que exibe o elemento modelo. Você também deve mapear as propriedades para os decoradores.

Para adicionar e exibir propriedades
  1. Adicione as propriedades.

    1. No diagrama de Definição de DSL, clique com o botão direito do mouse na classe de domínio Pessoa, aponte para Adicionar e clique em Propriedade de Domínio.

    2. Digite uma lista de novos nomes de propriedade, como Nascimento e Óbito. Pressione Enter depois de cada um.

  2. Adicione os decoradores que exibirão as propriedades na forma.

    1. Siga a linha cinza que se estende da classe de domínio Pessoa até o outro lado do diagrama. Este é um mapa de elementos do diagrama. Ele vincula a classe de domínio a uma classe de forma.

    2. Clique com o botão direito do mouse nessa classe de forma, aponte para Adicionar e clique em Decorador de Texto.

    3. Adicione dois decoradores com nomes como BirthDecorator e DeathDecorator.

    4. Selecione cada novo decorador e, na janela Propriedades, defina o campo Posição. Isso determina onde o valor da propriedade de domínio será exibido na forma. Por exemplo, defina InnerBottomLeft e InnerBottomRight.

      Definição da forma de compartimento

  3. Mapeie os decoradores para as propriedades.

    1. Abra a janela Detalhes de DSL. Geralmente, ela está em uma guia ao lado da janela Saída. Se não for possível vê-la, no menu Exibir, aponte para Outras Janelas e clique em Detalhes de DSL.

    2. No diagrama de definição de DSL, clique na linha que conecta a classe de domínio Pessoa à classe de forma.

    3. Em Detalhes de DSL, na guia Mapas de Decoradores, clique na caixa de seleção em um decorador não mapeado. Em Propriedade de Exibição, selecione a propriedade de domínio para a qual você deseja mapeá-la. Por exemplo, mapeie BirthDecorator para Nascimento.

  4. Salve a DSL, clique em Transformar Todos os Modelos e pressione F5.

  5. Em um diagrama de modelo de exemplo, verifique se agora você pode clicar nas posições escolhidas e digitar valores. Além disso, quando você seleciona uma forma de Pessoa, a janela Propriedades exibe as novas propriedades Nascimento e Óbito.

  6. Em um arquivo .tt, você pode adicionar o código que obtém as propriedades de cada pessoa.

    Gerenciador, caixa de ferramentas e diagrama de árvore genealógica

Definir novas classes

Você pode adicionar classes de domínio e relações a um modelo. Por exemplo, você pode criar uma nova classe para representar cidades e uma nova relação para representar que uma pessoa morou em uma cidade.

Para distinguir diferentes tipos em um diagrama de modelo, você pode mapear as classes de domínio para diferentes tipos de forma ou para formas com diferentes geometrias e cores.

Para adicionar e exibir uma nova classe de domínio
  1. Adicione uma classe de domínio e a torne filho da raiz do modelo.

    1. No diagrama de Definição de DSL, clique na ferramenta Relacionamento de Incorporação, clique na classe raiz FamilyTreeModel e clique em uma parte vazia do diagrama.

      Será exibida uma nova classe de domínio que está conectada ao FamilyTreeModel com um relacionamento de incorporação.

      Defina o nome, por exemplo, Cidade.

      Observação

      Cada classe de domínio, exceto a raiz do modelo, deve ser o destino de pelo menos um relacionamento de incorporação ou deve herdar de uma classe que seja o destino de uma incorporação. Por esse motivo, frequentemente convém criar uma classe de domínio usando a ferramenta Relacionamento de Incorporação.

    2. Adicione uma propriedade de domínio à nova classe, por exemplo, Nome.

  2. Adicione uma relação de referência entre Pessoa e Cidade.

    1. Clique na ferramenta Relação de Referência, clique em Pessoa e em Cidade.

      Fragmento de definição de DSL: raiz da árvore genealógica

      Observação

      As relações de referência representam referências cruzadas de uma parte da árvore de modelo para outra.

  3. Adicione uma forma para representar cidades nos diagramas do modelo.

    1. Arraste uma Forma Geométrica da caixa de ferramentas para o diagrama e renomeie, por exemplo, TownShape.

    2. Na janela Propriedades, defina os campos de Aparência da nova forma, como Cor de Preenchimento e Geometria.

    3. Adicione um Decorador para exibir o nome da cidade e renomeie como NameDecorator. Defina sua propriedade Posição.

  4. Mapeie a classe de domínio Cidade até TownShape.

    1. Clique na ferramenta Mapa de Elementos do Diagrama, então clique na classe de domínio Cidade e na classe de forma TownShape.

    2. Na guia Mapas de Decoradores da janela Detalhes de DSL com o conector de mapa selecionado, marque NameDecorator e defina Propriedade de Exibição como Nome.

  5. Crie um conector para exibir a relação entre Pessoa e Cidade.

    1. Arraste um Conector da caixa de ferramentas para o diagrama. Renomeie-o e defina as propriedades de aparência.

    2. Use a ferramenta Mapa de Elementos do Diagrama para vincular o novo conector à relação entre Pessoa e Cidade.

      Definição de árvore genealógica com o mapa de formas adicionado

  6. Crie uma ferramenta de elemento para criar uma nova Cidade.

    1. No Gerenciador de DSL, expanda Editor e, em seguida, Guias da Caixa de Ferramentas.

    2. Clique com o botão direito do mouse em <sua DSL> e clique em Adicionar Nova Ferramenta de Elemento.

    3. Defina a propriedade Nome da nova ferramenta e defina a propriedade Classe como Cidade.

    4. Defina a propriedade Ícone da Caixa de Ferramentas. Clique em [...] e, no campo Nome do arquivo, selecione um arquivo de ícone.

  7. Crie uma ferramenta de conector para criar um vínculo entre cidades e pessoas.

    1. Clique com o botão direito do mouse em <sua DSL> e clique em Adicionar Nova Ferramenta de Conector.

    2. Defina a propriedade Nome da nova ferramenta.

    3. Na propriedade ConnectionBuilder, selecione o construtor que contém o nome da relação Pessoa-Cidade.

    4. Defina o Ícone da Caixa de Ferramentas.

  8. Salve a Definição de DSL, clique em Transformar Todos os Modelos e pressione F5.

  9. Na instância experimental do Visual Studio, abra um arquivo de modelo de teste. Use as novas ferramentas para criar cidades e vínculos entre cidades e pessoas. Observe que você só pode criar links entre os tipos corretos de elemento.

  10. Crie um código que liste a cidade em que cada pessoa mora. Os modelos de texto são um dos locais em que você pode executar esse código. Por exemplo, você pode modificar o arquivo Sample.tt existente na solução de Depuração para que contenha o seguinte código:

    <#@ template inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation" debug="true" #>
    <#@ output extension=".txt" #>
    <#@ FamilyTree processor="FamilyTreeDirectiveProcessor" requires="fileName='Sample.ftree'" #>
    
    <#
      foreach (Person person in this.FamilyTreeModel.People)
      {
    #>
        <#= person.Name #><#if (person.Town != null) {#> of <#= person.Town.Name #> <#}#>
    
    <#
          foreach (Person child in person.Children)
      {
    #>
                <#= child.Name #>
    <#
      }
      }
    #>
    
    

    Quando você salvar o arquivo *.tt, isso criará um arquivo subsidiário que contém a lista de pessoas e suas residências. Para obter mais informações, confira Gerar código de uma linguagem específica de domínio.

Validação e comandos

Você pode desenvolver ainda mais essa DSL adicionando restrições de validação. Essas restrições são métodos que você pode definir, que garantem que o modelo esteja em um estado correto. Por exemplo, você pode definir uma restrição para garantir que a data de nascimento de um filho seja posterior à dos pais. O recurso de validação exibirá um aviso, se o usuário de DSL tentar salvar um modelo que viole qualquer uma das restrições. Para obter mais informações, confira Validação em uma linguagem específica de domínio.

Você também pode definir comandos de menu que o usuário pode invocar. Os comandos podem modificar o modelo. Eles também podem interagir com outros modelos no Visual Studio e com recursos externos. Para obter mais informações, confira Como modificar um comando de menu padrão.

Como implantar a DSL

Para permitir que outros usuários usem a linguagem específica de domínio, você distribuirá um arquivo de Extensão do Visual Studio (VSIX). Ele é criado quando você compila a solução DSL.

Localize o arquivo .vsix na pasta de compartimento da solução. Copie-o no computador em que você deseja instalá-lo. Nesse computador, clique duas vezes no arquivo VSIX. A DSL pode ser usada em todas as instâncias do Visual Studio nesse computador.

Você pode usar o mesmo procedimento para instalar a DSL no seu próprio computador para não precisar usar a instância experimental do Visual Studio.

Para obter mais informações, confira Implantando soluções de linguagem específica de domínio.

Como remover DSLs experimentais antigas

Se você criou DSLs experimentais que não são mais desejáveis, pode removê-las do computador redefinindo a instância experimental do Visual Studio.

Isso removerá do computador todas as DSLs experimentais e outras extensões experimentais do Visual Studio. Elas são extensões que foram executadas no modo de depuração.

Este procedimento não remove DSLs ou outras extensões do Visual Studio que foram totalmente instaladas executando o arquivo VSIX.

Para redefinir a instância experimental do Visual Studio

  1. No menu Iniciar do Windows, digite redefinir o Visual Studio e, em seguida, execute o comando Redefinir a Instância Experimental do Microsoft Visual Studio correspondente à sua versão do Visual Studio.

  2. Recompile as DSLs experimentais ou outras extensões experimentais do Visual Studio que você ainda deseja usar.