Compartilhar via


Introdução às Linguagens Específicas de Domínio

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

Observação

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

Se você for novo em DSLs, recomendamos que você trabalhe por meio do Laboratório de Ferramentas de DSL, que pode ser encontrado neste site: SDK de Visualização e Modelagem

O que você pode fazer com uma linguagem Domain-Specific?

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

Quando você tiver projetado uma DSL, poderá 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:

Diagrama da árvore familiar, caixa de ferramentas e explorer

A notação é apenas parte de uma DSL. Junto com a notação, seu pacote VSIX inclui ferramentas que os usuários podem aplicar para ajudá-los a editar e gerar material de seus modelos.

Um dos principais aplicativos de DSLs é gerar código do programa, arquivos de configuração e outros artefatos. Especialmente em grandes projetos e linhas de produtos, em que várias variantes de um produto serão criadas, gerar muitos dos aspectos variáveis das DSLs pode fornecer um grande aumento na confiabilidade e uma resposta muito rápida às alterações de 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 do domínio no Visual Studio.

Pré-requisitos

Para definir uma DSL, você deve ter instalado os seguintes componentes:

Componente Link
Visual Studio http://go.microsoft.com/fwlink/?LinkId=185579
Visual Studio SDK https://go.microsoft.com/fwlink/?linkid=2166172
SDK de modelagem para 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 da guia Componentes individuais .

Criar uma solução DSL

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

  1. No menu Arquivo , aponte para Novo e 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.

    Caixa de diálogo Criar DSL

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

    O Assistente de Linguagem Específica de Domínio é aberto e exibe uma lista de soluções de DSL de modelo.

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

    Os modelos são pontos de partida úteis. Cada uma delas fornece uma DSL funcional completa, que você pode editar conforme suas necessidades. Normalmente, você escolheria 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 os arquivos que contêm instâncias de sua DSL usarão.

    • Escolha uma extensão que não esteja associada a nenhum aplicativo em seu computador ou em qualquer computador em que você queira instalar a DSL. Por exemplo, docx e htm seriam extensões de nome de arquivo inaceitáveis.

    • O assistente avisará se a extensão que você inseriu estiver sendo usada como uma DSL. Considere usar uma extensão de nome de arquivo diferente. Você também pode redefinir a instância experimental do SDK do Visual Studio para limpar designers experimentais antigos. No menu Iniciar do Windows, digite redefinir o Visual Studio e 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 que contém dois projetos. Eles são chamados Dsl e DslPackage. Um arquivo de diagrama é aberto chamado DslDefinition.dsl.

    Observação

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

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

designer dsl

Essa solução define um idioma específico do domínio. Para obter mais informações, consulte Visão geral da Interface do Usuário das Ferramentas de Linguagem Domain-Specific.

As partes importantes da solução DSL

Observe os seguintes aspectos da nova solução:

  • Dsl\DslDefinition.dsl Esse é 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, consulte Como trabalhar com o diagrama de definição de DSL.

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

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

Executando a DSL

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

Para experimentar o 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 de DslDefinition.dsl.

    Observação

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

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

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

    Uma instância experimental do Visual Studio é iniciada. A instância experimental usa suas 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 do Gerenciador de Soluções.

    - ou -

    Clique com o botão direito do mouse no projeto de depuração, selecione Adicionar e clique em Item. Na caixa de diálogo Adicionar Item , selecione o tipo de arquivo de sua DSL.

    O arquivo de modelo é aberto como um diagrama em branco.

    A caixa de ferramentas é aberta e exibe as ferramentas apropriadas para o tipo de diagrama.

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

    1. Para criar formas, arraste 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 nas etiquetas das formas para alterá-las.

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

Árvore de exemplo de idioma específico do 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 ligações 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 de 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 aparece em um diagrama. Você pode escolher entre uma variedade de estilos de formas e conectores. Você pode especificar que algumas formas aparecem dentro de outras formas.

Você pode visualizar um modelo como uma árvore na visualização Explorer enquanto edita um modelo. À medida que você adiciona formas ao diagrama, os elementos de modelo também aparecem no explorer. O explorer pode ser usado mesmo se não houver nenhum 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, em seguida, clique em Seu Idioma Explorer.

A API do seu DSL

A sua DSL gera uma API que permite você ler e atualizar modelos que são instâncias da DSL. Um aplicativo da API é gerar arquivos de texto de um modelo. Para obter mais informações, consulte Design-Time Geração de Código 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 de modelos e permitir que você teste a API de sua DSL. Um dos exemplos é escrito no Visual Basic, o outro no Visual C#.

Em cada arquivo de modelo está o arquivo que ele gera. Expanda o arquivo de modelo no 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 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 de arquivo 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ê altera 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, consulte Gerando código de uma linguagem Domain-Specific e escrevendo código para personalizar um idioma Domain-Specific.

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 usando versões anteriores. Por exemplo, a solução de depuração contém um arquivo chamado Sample, que contém algumas formas e conectores. Depois que você começar a desenvolver sua definição de DSL, elas não estarão visíveis e serão perdidas quando você salvar o arquivo.

Você pode fazer uma ampla variedade de extensões para sua DSL. Os exemplos a seguir darão uma impressão das possibilidades.

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

Renomear os tipos e ferramentas

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

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

  1. No diagrama DslDefinition, renomeie ExampleModel como FamilyTreeModel, ExampleElement para Person, Targets to Parents e Sources to Children. Você pode clicar em cada rótulo para alterá-lo.

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

  2. Renomeie o elemento e as ferramentas do conector.

    1. Abra a janela do Explorador de DSL clicando na guia abaixo do Gerenciador de Soluções. Se você não conseguir vê-lo, no menu Exibir , aponte para Outras Janelas e clique no 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 para 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. Este é o item da caixa de ferramentas usado para criar elementos.

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

      Observe que a propriedade Caption também é alterada.

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

  3. Reconstruir 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 apareça.

  4. Na solução de Depuração na instância experimental do Visual Studio, abra um arquivo de modelo de teste. Arraste elementos para ele 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 ocorrências do tipo antigo e 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 às classes

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

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

Para adicionar propriedades e exibi-las
  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, selecione Adicionar e clique em Propriedade de Domínio.

    2. Digite uma lista de novos nomes de propriedades, como Nascimento e Morte. Pressione Enter após cada um deles.

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

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

    2. Clique com o botão direito do mouse nesta 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 do compartimento

  3. Mapeie os decoradores para as propriedades.

    1. Abra a janela Detalhes da DSL. Geralmente, ele está em uma guia ao lado da janela de Saída. Se você não conseguir vê-lo, 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 Person à classe de forma.

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

  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 neles. Além disso, quando você seleciona uma forma Pessoa, a janela de propriedades exibe as novas propriedades de Nascimento e Morte.

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

    Diagrama da árvore familiar, caixa de ferramentas e explorer

Definir novas classes

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

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

Para adicionar e exibir uma nova classe de domínio
  1. Adicione uma classe de domínio e torne-a um 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.

      Uma nova classe de domínio é exibida, que está conectada ao FamilyTreeModel com uma relação de inserção.

      Defina seu nome, por exemplo , Cidade.

      Observação

      Cada classe de domínio, exceto a raiz do modelo, deve ser o destino de pelo menos uma relação de inserção ou deve herdar de uma classe que seja o destino de uma inserção. Por esse motivo, é frequentemente conveniente criar uma classe de domínio usando a ferramenta Relação de Inserção.

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

  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 clique 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 de modelo.

    1. Arraste uma Forma de Geometria da caixa de ferramentas para o diagrama e renomeie-a, por exemplo , TownShape.

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

    3. Adicione um Decorador para exibir o nome da cidade e renomeá-lo nameDecorator. Defina a propriedade Position.

  4. Mapeie a classe de domínio Town para o TownShape.

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

    2. Na guia Mapas do Decorador 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 Person e Towns.

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

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

      Definição de Árvore de Família com mapa de formas adicionado

  6. Crie uma ferramenta para criar uma nova Cidade.

    1. No Gerenciador de DSL, expanda o Editor e as 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 Name da nova ferramenta e defina sua propriedade Class como Town.

    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 conexão para fazer 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 Name da nova ferramenta.

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

    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 lista a cidade na qual cada pessoa reside. 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 ele 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, ele criará um arquivo subsidiária que contém a lista de pessoas e suas residências. Para obter mais informações, consulte Gerando código de uma linguagem Domain-Specific.

Validação e comandos

Você pode desenvolver essa DSL ainda mais 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 uma criança seja posterior à de seus pais. O recurso de validação exibirá um aviso se o usuário DSL tentar salvar um modelo que interrompa qualquer uma das restrições. Para obter mais informações, consulte Validação em uma linguagem Domain-Specific.

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, consulte Como modificar um comando de menu padrão.

Implantando a DSL

Para permitir que outros usuários usem o idioma específico do domínio, distribua um arquivo VSIX (Extensão do Visual Studio). Isso é criado quando você cria a solução DSL.

Localize o arquivo .vsix na pasta bin da solução. Copie-o para o computador no qual 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 em seu próprio computador para não precisar usar a instância experimental do Visual Studio.

Para obter mais informações, consulte Implantando soluções de linguagem Domain-Specific.

Removendo DSLs experimentais antigas

Se você tiver criado DSLs experimentais que não deseja mais, poderá 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. Estas são extensões que foram executadas em 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 execute o comando Redefinir a Instância Experimental do Microsoft Visual Studio correspondente à sua versão do Visual Studio.

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