Definir uma Linguagem Específica por Domínio

Para definir uma linguagem específica de domínio (DSL), crie uma solução do Visual Studio a partir de um modelo. A parte fundamental da solução é o diagrama de Definição de DSL, que é armazenado em DslDefinition.dsl. A Definição de DSL define as classes e formas da DSL. Depois de modificar e adicionar esses elementos, você pode adicionar o código do programa para personalizar a DSL com mais detalhes.

Se DSLs são uma novidade para você, recomendamos que trabalhe com o DSL Tools Lab, que pode ser encontrado neste site: SDK de Visualização e Modelagem

Selecionando uma solução de modelo

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

  • Visual Studio
  • Carga de trabalho de desenvolvimento de extensão do Visual Studio (inclui o SDK do Visual Studio)
  • Modelagem do SDK (instale-o como um componente individual no 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.

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.

Para criar uma solução DSL

  1. Crie um novo projeto de Linguagem Específica do Domínio.

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

  2. Clique em cada modelo para ver uma descrição. Escolha a solução que mais se assemelha ao que você deseja criar.

    Cada modelo DSL define uma DSL de trabalho básica. Você editará essa DSL para atender aos seus próprios requisitos.

    Clique em cada exemplo para obter mais informações.

    • Escolha Fluxo de Tarefa para criar uma DSL que tenha raias. As raias são partições verticais ou horizontais do diagrama.

    • Escolha Modelos do Componente para criar uma DSL que tenha portas. As portas são pequenas formas na borda de uma forma maior.

    • Escolha Diagramas de Classe para definir uma DSL que tenha formas do compartimento. As formas do compartimento contêm listas de itens.

    • Escolha Linguagem Mínima em outros casos ou se você não tiver certeza.

    • Selecione Designer WinForm Mínimo ou Designer WPF Mínimo para criar uma DSL para ser exibida em uma superfície do Windows Forms ou WPF. Você precisará gravar um código para definir o editor. Para obter mais informações, consulte estes tópicos:

      Criando uma linguagem específica do domínio baseada no Windows Forms

      Criando uma linguagem específica de domínio baseada no WPF

  3. 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 de nome de arquivo que não esteja associada a nenhum aplicativo em seu computador ou em nenhum computador 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.

  4. Você pode ajustar as configurações nas outras páginas ou manter os valores padrão.

  5. Clique em Concluir.

    O assistente cria uma solução que contém dois ou três projetos e gera código a partir da definição da DSL.

    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.

Testar a solução

A solução de modelo fornece uma DSL de trabalho, que pode ser modificada ou usada da forma como se encontra.

Para testar a solução, pressione F5 ou CTRL+F5. Uma nova instância de Visual Studio se abre em modo experimental.

Na nova instância do Visual Studio, no Gerenciador de Soluções, abra o arquivo Exemplo. Ele se abre como um diagrama, com uma caixa de ferramentas.

Se você executar uma solução criada a partir do modelo Linguagem Mínima, seu Visual Studio experimental se assemelhará ao seguinte exemplo:

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

Experimente com as ferramentas. Crie elementos e os conecte.

Feche a Instância Experimental do Visual Studio.

Observação

Após modificar a DSL, não será possível mais ver as formas no arquivo de teste Exemplo. Entretanto, poderá criar novos elementos.

Modificando a DSL do modelo

Renomeie e mantenha algumas ou todas as classes de domínio e classes de formas na definição da DSL do modelo. Os novos nomes de classes devem ser nomes de CLR válidos, sem espaços ou pontuação.

É especialmente útil manter estas classes:

  • A classe raiz aparece no canto superior esquerdo do diagrama de Definição de DSL, em Classes e Relações. Renomeie-a com um nome diferente da DSL. Por exemplo, uma DSL chamadaMusicLibrary pode ter uma classe raiz chamada Music.

  • A classe de diagrama aparece no canto inferior direito do diagrama de Definição de DSL, na coluna Elementos do Diagrama. Talvez seja necessário rolar para a direita para vê-la. Ela é geralmente chamada de YourDslDiagram.

  • Se você usou o modelo do Fluxo de Tarefa e deseja criar diagramas com raias, mantenha e renomeie a classe de domínio Ator e a forma ActorSwimlane.

    Exclua ou renomeie outras classes para atender aos seus requisitos.

Padrões para definir uma DSL

Recomendamos que você desenvolva uma DSL adicionando ou ajustando um ou dois recursos por vez. Adicione um recurso, execute a DSL e teste-a, em seguida, adicione um ou dois recursos adicionais. Um recurso típico de sua DSL pode ser:

  • Uma classe de domínio, a relação de incorporação que conecta o elemento ao modelo, a forma necessária para exibir elementos dessa classe no diagrama e a ferramenta do elemento que permite aos usuários criar elementos.

  • As propriedades de domínio de uma classe de domínio e os decoradores que as exibem em uma forma.

  • Uma relação de referência e o conector que a exibe no diagrama, bem como a ferramenta de conector que permite aos usuários criar vínculos.

  • Uma personalização que exige código do programa, tal como uma restrição de validação ou um comando de menu.

    As seções a seguir descrevem como construir os tipos mais úteis de recursos DSL. Há vários outros padrões com os quais uma DSL pode ser construída, mas esses são os usados com mais frequência.

Observação

Depois de adicionar um recurso, não se esqueça de clicar em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções antes de compilar e executar sua DSL.

A figura a seguir mostra as classes e relações que fazem parte da DSL usada de exemplo neste tópico.

Relações de inserção e referência

A próxima figura é um modelo de exemplo desta DSL:

Modelo de instância do DSL gerado

Observação

"Modelo" refere-se a uma instância de sua DSL que os usuários criam e geralmente é exibida como um diagrama. Este tópico discute o diagrama da Definição de DSL e os diagramas de modelo que aparecem quando sua DSL é usada.

Definindo as classes de domínio

As classes de domínio representam os conceitos de sua DSL. As instâncias são elementos de modelo. Por exemplo, em uma DSL MusicLibrary, você pode ter Classes de Domínio chamadas de Álbum e Canção.

Para criar uma classe de domínio, você pode arrastar da ferramenta Classe de Domínio Nomeada para o diagrama e, em seguida, renomear a classe.

Para obter mais informações, consulte Propriedades de classes de domínio.

Criar uma relação de incorporação para cada classe de domínio

Cada classe de domínio, exceto a classe raiz, deve ser o destino de pelo menos uma relação incorporada ou ela deve herdar de uma classe que seja o destino de uma relação de incorporação.

Em um modelo, todo elemento de modelo é um nó em uma única árvore de relações de incorporação. A origem e o destino de uma relação de incorporação são geralmente chamados de pai e filho.

A seleção de um pai para uma classe de domínio depende de como você deseja que os tempos de vida de seus elementos dependam de outros elementos. Se um nó de uma árvore for excluído, sua subárvore geralmente também será excluída. Classes de elementos que tenham uma existência independente são, portanto, inseridas diretamente na classe raiz.

Geralmente, ao exibir um elemento dentro de outro elemento, você deseja indicar uma relação de propriedade. Nesse caso, a classe pai mais apropriada é a classe do contêiner. A exceção é quando o item que você vê dentro de um contêiner é, na verdade, apenas um vínculo de referência a um elemento independente. Nesse caso, a exclusão do contêiner exclui a referência, mas não seu destino.

Nos padrões de definição de DSL descritos neste tópico, assumiremos que os elementos exibidos dentro de um contêiner serão excluídos quando o contêiner for excluído. Esquemas mais complexos são possíveis e podem ser obtidos pela definição de regras.

Como o elemento é exibido Classe pai (incorporação) Exemplo no modelo de solução DSL
Forma no diagrama.

Raia.
Classe raiz da DSL. Linguagem Mínima.

Fluxo de Tarefa: classe Ator.
Forma na raia. Classe de domínio de elementos que são exibidos como raias. Fluxo de Tarefa: classe Tarefa.
Item na lista em forma, em que o item será excluído se o contêiner for excluído.

Porta na borda da forma.
Classe de domínio mapeada conforme a forma do contêiner. Diagrama de classe: classe Atributo.

Diagrama de componente: classe Porta.
Item na lista, não excluído se o contêiner for excluído. Classe raiz da DSL.

A lista exibe vínculos de referência.
Não exibido diretamente. A classe da qual ela forma parte.

No exemplo de Biblioteca de Músicas, Álbuns são exibidos como retângulos nos quais os títulos das Canções são listados. Portanto, o pai de Álbum é a classe raiz Música e o pai de Canção é Álbum.

Para criar uma classe de domínio e sua incorporação ao mesmo tempo, clique na ferramenta Relação de Integração, clique na classe pai e, em seguida, em uma parte em branco do diagrama.

Geralmente não é necessário ajustar o nome da relação de incorporação e de suas funções, pois acompanharão os nomes de classes automaticamente.

Para obter mais informações, consulte Propriedades de relações de domínio e propriedades de funções de domínio.

Observação

Incorporação não é o mesmo que herança. Os filhos em uma relação de incorporação não herdam recursos de seus pais.

Adicionar propriedades de domínio em cada classe de domínio

As propriedades de domínio armazenam valores. Os exemplos são: Nome, Título, Data de Publicação.

Clique em Propriedades de Domínio na classe, pressione a tecla ENTER e digite o nome de uma propriedade. O tipo padrão de uma propriedade de domínio é a Cadeia de Caracteres. Se você desejar alterar o tipo, escolha a propriedade de domínio e configure o Tipo na janela Propriedades. Se o tipo que você deseja não estiver na lista suspensa, consulte Adicionando tipos de propriedades.

Configure uma propriedade de Nome de Elemento. Selecione uma propriedade de domínio que possa ser usada para identificar elementos no gerenciador de linguagens. Por exemplo, na classe de domínio Canção que você poderia escolher a propriedade de domínio Título. Na janela Propriedades, configure É Nome de Elemento como true.

Criar classes de domínio derivadas

Se você deseja que uma classe de domínio tenha variantes que herdam suas propriedades e relações, crie classes que derivam dela. Por exemplo, Álbum pode ter as classes derivadas WMA e MP3.

Crie a classe derivada usando a ferramenta Classe de Domínio.

Clique na ferramenta Herança, clique na classe derivada e na classe base.

Considere configurar o Modificador de Herança da classe base como abstrato. Se você acha que talvez precise de instâncias da classe base, considere, em vez disso, criar uma classe derivada separada para elas.

As classes derivadas herdam as propriedades e funções de suas classes base.

Organizar o diagrama de Definição de DSL

Ao adicionar relações, algumas de suas classes aparecerão em mais de um lugar. Para reduzir o número de aparições e tornar o diagrama mais amplo, clique com o botão direito do mouse na classe de destino de uma relação e clique em Trazer Árvore Aqui. Para obter o efeito oposto, clique com o botão direito do mouse na classe de destino de uma relação e clique em Dividir Árvore. Se você não vir esses comandos de menu, certifique-se de que apenas a classe de domínio esteja escolhida.

Use CTRL+Seta para Cima e CTRL+Seta para Baixo para mover as classes de domínio e as classes de forma.

Testar as classes de domínio

Para testar as novas classes de domínio
  1. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções, para gerar o código de designer DSL. Você pode automatizar esta etapa. Para obter mais informações, confira Como automatizar a transformação de todos os modelos.

  2. Compile e execute a DSL. Pressione F5 ou CTRL+F5 para executar uma nova instância do Visual Studio em modo experimental. Na instância experimental do Visual Studio, abra ou crie um arquivo que tenha a extensão de nome de arquivo de sua DSL.

  3. Abra o Gerenciador. Ao lado do diagrama está a janela do gerenciador de linguagens, que é geralmente chamada de Gerenciador YourLanguage. Se você não vir essa janela, ela pode estar em uma guia no Gerenciador de Soluções. Se você não a encontrar, no menu Exibir, aponte para Outras Janelas e clique em YourLanguageGerenciador.

    Seu gerenciador apresentará uma exibição em árvore do modelo.

  4. Crie novos elementos. Clique com o botão direito do mouse no nó raiz na parte superior e clique em Adicionar novoYourClass.

    Uma nova instância de sua classe aparecerá no Gerenciador de linguagens.

  5. Verifique se cada instância possui um nome diferente ao criar novas instâncias. Isso ocorrerá somente se você tiver configurado o sinalizador É Nome de Elemento em uma propriedade do domínio.

  6. Examine as propriedades do domínio. Com uma instância da classe selecionada, inspecione a janela Propriedades. Ela deve mostrar as propriedades de domínio definidas nesta classe de domínio.

  7. Salve o arquivo, feche-o e abra-o novamente. Após a expansão dos nós, todas as instâncias criadas devem estar visíveis no gerenciador.

Definindo formas no diagrama

Você pode definir as classes de elementos que aparecem em um diagrama como retângulos, elipses ou ícones.

Para definir uma classe de elementos que aparece como formas em um diagrama

  1. Defina e teste uma classe de domínio, conforme descrito emDefinindo as classes de domínio.

    • O pai da classe deve ser a classe raiz. Ou seja, deve haver uma relação de incorporação entre a classe raiz e a nova classe de domínio.

    • Se o seu diagrama tiver raias, o pai pode ser a classe de domínio que é mapeada para uma raia. Antes de continuar com este procedimento, consulte Definindo uma DSL que possui raias.

  2. Adicione uma classe de forma para representar os elementos no diagrama de modelo. Arraste de uma das seguintes ferramentas para o diagrama de Definição de DSL:

    • Forma geométrica fornece um retângulo ou uma elipse.

    • Forma de imagem exibe uma imagem fornecida por você.

    • A forma do compartimento é um retângulo que contém uma ou mais listas de itens.

      Renomeie a classe de formas, a qual aparecerá no lado direito do diagrama de Definição de DSL, em Formas e Conectores.

  3. Defina uma imagem, se você criou uma forma de imagem.

    1. Crie um arquivo de imagem de qualquer tamanho. Os formatos BMP, JPEG, GIF e EMF são compatíveis.

    2. No Gerenciador de Soluções, adicione o arquivo à solução em Dsl\Resources.

    3. Retorne ao diagrama de Definição de DSL e selecione a nova classe de forma de imagem.

    4. Na janela Propriedades, clique na propriedade Imagem.

    5. Na caixa de diálogo Selecionar Imagem, clique no menu suspenso em Nome do arquivo e selecione a imagem.

  4. Adicione decoradores de texto à forma para exibir as propriedades do domínio.

    Para exibir o nome ou o título do elemento de modelo, você provavelmente precisará de pelo menos um decorador de texto.

    Clique com o botão direito do mouse na classe de forma, aponte para Adicionar e clique em Decorador de Texto. Configure o nome do decorador e, na janela Propriedades, configure sua Posição.

  5. Conecte cada forma com um Mapa de Elemento do Diagrama à classe de domínio que ela deve exibir.

    Clique na ferramenta Mapa de Elemento do Diagrama, na classe de domínio e na classe de forma.

  6. Mapeie as propriedades para os decoradores de texto.

    1. Selecione a linha cinza entre a classe de domínio e a classe de forma que representa o mapa de elemento do diagrama.

    2. Na janela Detalhes de DSL, clique na guia Mapas do decorador. Se você não visualizar a janela Detalhes de DSL, no menu exibir, aponte para Outras janelas e clique em Detalhes de DSL. Normalmente é necessário aumentar a parte superior desta janela para ver todo o seu conteúdo.

    3. Escolha o nome de um decorador. Em Exibir propriedade, selecione o nome de uma propriedade da classe de domínio. Repita isso para cada decorador.

      Se desejar exibir uma propriedade de um elemento relacionado, clique no navegador de árvore suspenso em Caminho para exibir propriedade.

    4. Certifique-se de que haja uma marca de seleção ao lado de cada nome de decorador.

      Janela Mapeamentos de Formas e Detalhes de DSL

  7. Crie um item da caixa de ferramentas para criar elementos da classe de domínio.

    1. No Gerenciador de DSL, expanda o nó Editor e todos os seus subnós.

    2. Clique com o botão direito do mouse no nó nas Guias da Caixa de Ferramentas que tenham o mesmo nome de sua DSL, por exemplo, MusicLibrary. Clique em Adicionar Ferramenta de Elemento.

      Observação

      Se você clicar com o botão direito do mouse no nó Ferramentas, não verá Adicionar Ferramenta de Elemento. Em vez disso, clique no nó acima dele.

    3. Na janela Propriedades, com a nova ferramenta de elemento selecionada, configure Classe como a classe de domínio recém-adicionada.

    4. Configure Legenda e Dica de Ferramenta.

    5. Configure Ícone da Caixa de Ferramentas como um ícone que aparecerá na caixa de ferramentas. Você pode configurá-lo como um novo ícone ou um ícone já usado por outra ferramenta.

      Para criar um novo ícone, abra Dsl\Resources no Gerenciador de Soluções. Copie e cole um dos arquivos BMP da ferramenta de elemento existente. Renomeie a cópia colada e clique duas vezes para editá-la.

      Retorne ao diagrama de Definição de DSL, selecione a ferramenta e, na janela Propriedades, clique em [...] no Ícone da Caixa de Ferramentas. Na caixa de diálogo Selecionar Bitmap, selecione o arquivo BMP no menu suspenso.

    Para obter mais informações, consulte Propriedades de formas de geometria e Propriedades de formas de imagem.

Para testar as formas

  1. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções, para gerar o código de designer DSL.

  2. Compile e execute a DSL. Pressione F5 ou CTRL+F5 para executar uma nova instância do Visual Studio em modo experimental. Na instância experimental do Visual Studio, abra ou crie um arquivo que tenha a extensão de nome de arquivo de sua DSL.

  3. Verifique se as ferramentas de elemento aparecem na caixa de ferramentas.

  4. Crie formas arrastando de uma ferramenta para o diagrama de modelo.

  5. Verifique se cada decorador de texto aparece e se:

    1. Você pode editá-lo, a menos que tenha configurado o sinalizador É IU Somente Leitura na propriedade do domínio.

    2. Quando você edita a propriedade na janela Propriedades ou no decorador, a outra exibição é atualizada.

    Depois de testar inicialmente uma forma, talvez você queira ajustar algumas de suas propriedades e adicionar outros recursos mais avançados. Para obter mais informações, consulte Personalizando e estendendo uma linguagem específica de domínio.

Definindo relações de referência

Você pode definir uma relação de referência entre qualquer classe de domínio de origem e qualquer classe de domínio de destino. As relações de referência são geralmente exibidas em um diagrama como conectores, que são linhas entre formas.

Por exemplo, se Álbuns de música e Artistas forem exibidos como formas no diagrama, será possível definir um relação chamada ArtistsAppearedOnAlbums, a qual vincula os Artistas aos Álbuns nos quais eles trabalharam. Veja o exemplo na figura.

Modelo de instância do DSL gerado

As relações de referência também podem vincular elementos do mesmo tipo. Por exemplo, em uma DSL que representa uma árvore genealógica, a relação entre pais e seus filhos é uma relação de referência de Pessoa a Pessoa.

Definir uma relação de referência

Clique na ferramenta Relação de Referência, na classe de domínio de origem da relação e na classe de domínio de destino. A classe de destino pode ser a mesma que a classe de origem.

Cada relação possui duas funções, representadas pela linha de cada lado da caixa de relação. Você pode selecionar cada função e configurar suas propriedades na janela Propriedades.

Considere renomear as funções. Por exemplo, em uma relação entre Pessoa e Pessoa, talvez você queira alterar os nomes padrão para Pais e Filhos, Gerente e Subordinados, Professor e Aluno, etc.

Ajuste as multiplicidades de cada função, se for necessário. Se você deseja que cada Pessoa tenha no máximo um Gerente, configure a multiplicidade que aparece abaixo do rótulo Gerente no diagrama como 0..1.

Adicione propriedades de domínio à relação. Na figura, a relação Artista-Álbum tem uma propriedade de função.

Configure a propriedade Permite duplicatas se mais de um vínculo da mesma classe puder existir entre o mesmo par de elementos de modelo. Por exemplo, você poderia permitir que um Professor ensinasse mais de uma Matéria para o mesmo Aluno.

Mapas de formas para conectores

Para obter mais informações, consulte Propriedades de relações de domínio e propriedades de funções de domínio.

Definir um conector para exibir a relação

Um conector exibe uma linha entre duas formas no diagrama do modelo.

Arraste a ferramenta Conector para o diagrama de definição de DSL.

Adicione decoradores de texto se desejar exibir rótulos no conector. Configure suas posições. Para permitir que o usuário mova um decorador de texto, configure sua propriedade É Movível.

Use a ferramenta Mapa de Elemento do Diagrama para vincular o conector à relação de referência.

Com o mapa de elemento do diagrama selecionado, abra a janela Detalhes de DSL e abra a guia Mapas do Decorador.

Selecione cada Decorador e configure Exibir propriedade como a propriedade de domínio correta.

Certifique-se de que exista uma marca de seleção ao lado de cada item na lista Decoradores.

Definir uma ferramenta do construtor de conexões

Na janela Gerenciador de DSL, expanda o nó Editor e todos os seus subnós.

Clique com o botão direito do mouse no nó com o mesmo nome de sua DSL e clique em Adicionar Nova Ferramenta de Conexão.

Enquanto a nova ferramenta estiver selecionada, na janela Propriedades:

  • Configure a Legenda e a Dica de Ferramenta.

  • Clique em Construtor de Conexões e escolha o construtor apropriado para a nova relação.

  • Configure Ícone da Caixa de Ferramentas como um ícone que deseja que apareça na caixa de ferramentas. Você pode configurá-lo como um novo ícone ou um ícone já usado por outra ferramenta.

    Para criar um novo ícone, abra Dsl\Resources no Gerenciador de Soluções. Copie e cole um dos arquivos BMP da ferramenta de elemento existente. Renomeie a cópia colada e clique duas vezes para editá-la.

    Retorne ao diagrama de Definição de DSL, selecione a ferramenta e, na janela Propriedades, clique em [...] no Ícone da Caixa de Ferramentas. Na caixa de diálogo Selecionar Bitmap, selecione o arquivo BMP no menu suspenso.

Para Testar um relação de Referência e um Conector
  1. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções, para gerar o código de designer DSL.

  2. Compile e execute a DSL. Pressione F5 ou CTRL+F5 para executar uma nova instância do Visual Studio em modo experimental. Na instância experimental do Visual Studio, abra ou crie um arquivo que tenha a extensão de nome de arquivo de sua DSL.

  3. Verifique se a ferramenta de conexão aparece na caixa de ferramentas.

  4. Crie formas arrastando de uma ferramenta para o diagrama de modelo.

  5. Crie conexões entre as formas. Clique na ferramenta do conector, em uma forma e em outra forma.

  6. Verifique se você não pode criar conexões entre classes inadequadas. Por exemplo, se a sua relação for entre Álbuns e Artistas, verifique se não é possível vincular Artistas a Artistas.

  7. Verifique se as multiplicidades estão corretas. Por exemplo, verifique se você não pode conectar uma Pessoa a mais de um gerente.

  8. Verifique se cada decorador de texto aparece e se:

    1. Você pode editá-lo, a menos que tenha configurado o sinalizador É IU Somente Leitura na propriedade do domínio.

    2. Quando você edita a propriedade na janela Propriedades ou no decorador, a outra exibição é atualizada.

    Depois de testar inicialmente um conector, talvez você queira ajustar algumas de suas propriedades e adicionar outros recursos mais avançados. Para obter mais informações, consulte Personalizando e estendendo uma linguagem específica de domínio.

Definindo formas que contêm listas: formas do compartimento

Uma forma do compartimento contém uma ou mais listas de itens. Por exemplo, em uma DSL de Biblioteca de Músicas, você poderia usar formas do compartimento para representar os Álbuns de música. Em cada Álbum, há uma lista de Canções.

Forma do compartimento

No método mais simples de obter esse efeito em uma definição de DSL, você define uma classe de domínio para o contêiner e uma classe de domínio para cada lista. A classe de contêiner é mapeada para a forma do compartimento.

Mapa de formas

Para obter mais informações, consulte Propriedades de formas de compartimento.

Para definir uma forma do compartimento

  1. Crie a classe de domínio do contêiner. Clique na ferramenta Relação de Incorporação, clique na classe raiz do modelo e em uma parte em branco do diagrama de definição de DSL. Com isso, você cria a classe de domínio chamada Álbum na figura de exemplo.

    Como alternativa, em vez de incorporar na classe raiz, você pode incorporar o contêiner em uma classe de domínio que seja mapeada para uma raia.

    Adicione uma propriedade de domínio, tal como o Nome, à classe e configure o sinalizador É Nome de Elemento na janela Propriedades.

  2. Crie a classe de domínio do item de lista. Clique na ferramenta Relação de Incorporação, clique na classe do contêiner (Álbum) e em uma parte em branco do diagrama. Com isso, você cria a classe de domínio chamada Canção na figura de exemplo.

    Adicione uma propriedade de domínio, tal como o Título, à classe e configure o sinalizador É Nome de Elemento.

    Adicione outras propriedades de domínio.

    Adicione outra classe de domínio do item de lista que você deseja exibir.

  3. Para combinar vários tipos de itens na lista, crie classes herdadas da classe de lista. Torne a classe de lista abstrata configurando seu Modificador de Herança.

    Por exemplo, se você desejar que música clássica seja classificada por compositor em vez de por artista, é possível criar duas subclasses de Canção, ClassicalSong e NonClassicalSong.

  4. Crie a forma do compartimento. Arraste a ferramenta Forma do Compartimento no diagrama de definição de DSL.

    Adicione um decorador de texto e defina seu nome.

    Adicione um compartimento e defina seu nome.

  5. Para permitir que o usuário oculte os compartimentos da lista, clique com o botão direito do mouse na classe de forma do compartimento, aponte para Adicionar e clique em Expandir/Recolher Decorador. Na janela Propriedades, configure a posição do decorador.

  6. Clique na ferramenta Mapa de Elemento do Diagrama, clique na classe de domínio do contêiner e na forma do compartimento.

  7. Selecione o vínculo de mapa do elemento do diagrama entre a classe de domínio e a forma. Na janela Detalhes de DSL:

    1. Clique na guia Decoradores. Clique no nome do decorador e escolha o item apropriado em Exibir Propriedade. Certifique-se de que exista uma marca de seleção ao lado do nome do decorador.

    2. Clique na guia Mapas de Compartimento.

      Clique no nome do compartimento.

      Em Caminho da coleção de elementos exibidos, navegue até a classe de elementos da lista (Canção). Clique na seta suspensa para usar a ferramenta de navegador.

      Em Exibir Propriedade, escolha a propriedade que deve ser exibida na lista. No exemplo, será Título.

Observação

Usando os campos Caminho nos campos de Mapa do Decorador e Mapa de Compartimento, é possível tornar as relações entre as classes de domínio e a forma do compartimento mais complexas.

Para definir uma ferramenta para criar a forma

  1. Crie um item da caixa de ferramentas para criar elementos da classe de domínio.

  2. No Gerenciador de DSL, expanda o nó Editor e todos os seus subnós.

  3. Clique com o botão direito do mouse no nó nas Guias da Caixa de Ferramentas que tenham o mesmo nome de sua DSL, por exemplo, MusicLibrary. Clique em Adicionar Ferramenta de Elemento.

    Observação

    Se você clicar com o botão direito do mouse no nó Ferramentas, não verá Adicionar Ferramenta de Elemento. Em vez disso, clique no nó acima dele.

  4. Na janela Propriedades, com a nova ferramenta de elemento selecionada, configure Classe como a classe de domínio recém-adicionada.

  5. Configure Legenda e Dica de Ferramenta.

  6. Configure Ícone da Caixa de Ferramentas como um ícone que aparecerá na caixa de ferramentas. Você pode configurá-lo como um novo ícone ou um ícone já usado por outra ferramenta.

    Para criar um novo ícone, abra Dsl\Resources no Gerenciador de Soluções. Copie e cole um dos arquivos .BMP da ferramenta de elemento existente. Renomeie a cópia colada e clique duas vezes para editá-la.

    Retorne ao diagrama de Definição de DSL, selecione a ferramenta e, na janela Propriedades, clique em [...] no Ícone da Caixa de Ferramentas. Na caixa de diálogo Selecionar Bitmap, selecione o arquivo BMP no menu suspenso.

Para testar uma forma do compartimento

  1. Clique em Transformar Todos os Modelos na barra de ferramentas do Gerenciador de Soluções, para gerar o código de designer DSL.

  2. Compile e execute a DSL. Pressione F5 ou CTRL+F5 para executar uma nova instância do Visual Studio em modo experimental. Na instância experimental do Visual Studio, abra ou crie um arquivo que tenha a extensão de nome de arquivo de sua DSL.

  3. Verifique se a ferramenta aparece na caixa de ferramentas.

  4. Arraste a ferramenta para o diagrama de modelo. Com isso, uma forma é criada.

    Verifique se o nome do elemento aparece e é configurado automaticamente como um valor padrão.

  5. Clique com o botão direito do mouse no cabeçalho da nova forma e clique em Adicionar Seu Item de Lista. No exemplo, o comando é Adicionar Canção.

    Verifique se aparece um item na lista e se ele tem um novo nome.

  6. Clique em um dos itens da lista e examine a janela Propriedades. Você deve ver as propriedades dos itens da lista.

  7. Abra o Gerenciador de linguagens. Verifique se você pode ver os nós do contêiner com os nós do item de lista dentro.

    Gerenciador de DSL gerado

    Depois de testar inicialmente uma forma do compartimento, talvez você queira ajustar algumas de suas propriedades e adicionar outros recursos mais avançados. Para obter mais informações, consulte Personalizando e estendendo uma linguagem específica de domínio.

Geralmente, um elemento que você exibe em um compartimento é um filho do elemento que é representado pela forma do compartimento. No entanto, algumas vezes, você pode desejar exibir um elemento que esteja vinculado a ele com uma relação de referência.

Por exemplo, podemos adicionar um segundo compartimento a AlbumShape que exibe uma lista dos Artistas que estão vinculados ao Álbum.

Nesse caso, o compartimento deve exibir o vínculo, e não o elemento referenciado. Isso ocorre porque quando o usuário seleciona o item no compartimento e pressiona DELETE, a intenção é que o link seja excluído, e não o elemento referenciado.

Entretanto, é possível fazer com que o nome do elemento referenciado apareça no compartimento.

O procedimento a seguir pressupõe que você já tenha criado a classe de domínio, a relação de referência, a forma do compartimento e o mapa de elemento de diagrama, conforme descrito anteriormente nesta seção.

  1. Adicione um compartimento à forma do compartimento. No diagrama de Definição de DSL, clique com o botão direito do mouse na classe da forma do compartimento, aponte para Adicionar e clique em Compartimento.

  2. Defina Caminho da coleção de elementos exibidos para navegar até o vínculo, e não até seu elemento de destino. Clique no menu suspenso e use a exibição em árvore para selecionar a relação de referência em vez de seu destino. No exemplo, o relação é ArtistAppearedOnAlbums.

  3. Defina o Caminho para Exibir Propriedade para navegar do vínculo ao elemento de destino. No exemplo, será Artista.

  4. Defina Exibir Propriedade para a propriedade apropriada do elemento de destino, por exemplo, Nome.

  5. Clique em Transformar Todos os Modelos, compile e execute a DSL e abra um modelo de teste.

  6. No diagrama de modelo, crie as classes de forma apropriadas, defina seus nomes e crie um vínculo entre eles. Na forma do compartimento, devem aparecer os nomes dos elementos vinculados.

  7. Selecione o vínculo ou o item na forma do compartimento. O vínculo e o item devem desaparecer.

Definindo as portas no limite de outra forma

Uma porta é uma forma que está localizada no limite de outra forma.

As portas também podem ser usadas para fornecer um ponto de conexão fixo em outra forma, no qual o usuário pode desenhar conectores. Nesse caso, você pode tornar a forma da porta transparente.

Para ver um exemplo que usa portas, selecione o modelo Diagrama de Componente ao criar uma nova solução DSL. Este exemplo mostra os pontos principais que você pode considerar ao definir as portas:

  • Há uma classe de domínio que representa o contêiner das portas, Component.

  • Há uma classe de domínio que representa portas. no exemplo, é ComponentPort.

  • Há uma relação de incorporação da classe de domínio de contêiner à classe de domínio de porta. Para obter mais informações, consulte Definindo as classes de domínio.

  • Se você deseja combinar tipos diferentes de portas no mesmo contêiner, é possível criar subclasses da classe de domínio da porta. No exemplo, InPort e OutPort são herdados de ComponentPort.

  • A classe de domínio de contêiner pode ser mapeada para qualquer tipo de forma. No exemplo, ela é ComponentShape. Para obter mais informações, consulte Definindo formas.

  • As classes de domínio de porta são mapeadas para formas de porta. Você pode mapear as classes derivadas para classes de forma de porta separadas ou mapear a classe base para uma classe de forma de porta.

    Em outros aspectos, as formas de portas se comportam conforme descrito em Definindo formas.

    Para obter mais informações, consulte Propriedades de formas de porta.

Definindo uma DSL que possui raias

As raias são uma partição horizontal ou vertical de um diagrama. Cada raia corresponde a um elemento de modelo. Sua definição de DSL requer uma classe de domínio para os elementos de raia.

A melhor maneira de criar uma DSL com raias é criar uma nova solução DSL e escolher o modelo de solução Fluxo de Tarefa. Na Definição de DSL, a classe Ator é a classe de domínio mapeada para a raia. Renomeie essa e as outras classes da forma adequada ao seu projeto.

Para adicionar uma classe que será exibida como uma forma dentro de uma raia, crie uma Relação de Incorporação entre a classe de raia e sua nova classe. Os usuários poderão arrastar elementos de uma raia para outra, mas cada elemento estará sempre dentro de uma raia específica. No modelo de solução Fluxo de Tarefa, FlowElement é um filho da classe de raia.

Para adicionar uma classe que será exibida como uma forma independentemente de raias, crie uma Relação de Incorporação entre a classe raiz e sua nova classe. Os usuários poderão colocar essas formas em qualquer lugar no diagrama, inclusive nos limites de raias e fora das raias. No modelo de solução Fluxo de Tarefa, Comment é um filho da classe raiz.

Para obter mais informações, consulte Propriedades de raias.

Adicionando tipos de propriedade

Enumerações e literais de domínio

Uma enumeração de domínio é um tipo com vários valores de literais.

Para adicionar uma enumeração de domínio, clique com o botão direito do mouse na raiz do modelo no Gerenciador de DSL e clique em Adicionar Nova Enumeração de Domínio. O elemento aparecerá no Gerenciador de DSL no nó Tipos de Domínio. Esse elemento não aparece no diagrama.

Para adicionar literais de enumeração na enumeração de domínio, clique com o botão direito do mouse na enumeração do domínio no Gerenciador de DSL e clique em Adicionar Nova Literal de Enumeração.

Por padrão, uma propriedade que possui um tipo de enumeração pode ser configurada para somente um valor de enumeração por vez. Se você desejar que os usuários e programadores possam configurar qualquer combinação de valores – um "campo de bits" – configure a propriedade IsFlags da Enumeração.

Tipos externos

Ao definir o tipo de uma propriedade de domínio, se você não encontrar o tipo desejado na lista suspensa Tipo, poderá adicionar um tipo externo. Por exemplo, você poderá adicionar o tipo System.Drawing.Color à lista.

Para adicionar um tipo, clique com o botão direito do mouse na raiz do modelo no Gerenciador de DSL e clique em Adicionar Novo Tipo Externo. No janela Propriedades, defina o nome como Cor e o namespace como System.Drawing. Esse tipo aparecerá agora no Gerenciador de DSL em Tipos de Domínio. Você pode escolhê-lo sempre que definir o tipo de uma propriedade de domínio.

Personalizando a DSL

Usando as técnicas descritas neste tópico, é possível criar com rapidez uma DSL com uma notação diagramática, uma forma XML legível e as ferramentas básicas necessárias para gerar código e outros artefatos.

Há dois métodos de extensão da definição de DSL:

  1. Ajuste a DSL usando mais recursos da Definição de DSL. Por exemplo, você pode criar uma única ferramenta de conector capaz de criar vários tipos de conectores e você pode controlar as regras com as quais a exclusão de um elemento também exclui elementos relacionados. Essas técnicas são obtidas, em sua maioria, ao configurar valores na Definição de DSL, e alguns deles necessitam de algumas linhas do código do programa.

    Para obter mais informações, consulte Personalizando e estendendo uma linguagem específica de domínio.

  2. Estenda suas ferramentas de modelagem usando o código do programa para obter efeitos mais avançados. Por exemplo, você pode criar comandos de menu que alteram o modelo e você pode criar ferramentas que integram duas ou mais DSLs. O VMSDK foi projetado especificamente para facilitar a integração de suas extensões com o código gerado a partir da Definição de DSL. Para obter mais informações, confira Escrever código para personalizar uma linguagem específica de domínio.

Alterando a definição de DSL

Ao criar qualquer item em uma definição de DSL, diversos valores padrão são configurados automaticamente. Depois de configurados, você poderá alterá-los. Isso simplifica o desenvolvimento de uma DSL e ainda permite personalizações avançadas.

Por exemplo, quando você mapeia uma forma para um elemento, o Caminho do Elemento Pai do mapeamento é configurado automaticamente, de acordo com a relação de incorporação da classe de domínio. Entretanto, se posteriormente você alterar a relação de incorporação, o caminho do elemento pai não é alterado automaticamente.

Você deve, portanto, estar ciente de que ao alterar algumas relações em sua Definição de DSL, não é incomum que erros sejam relatados ao salvar a definição ou ao Transformar Todos os Modelos. A maioria dos erros é fácil de corrigir. Clique duas vezes no relatório de erros para ver o local do erro.

Confira também Como alterar o namespace de uma linguagem específica do domínio.

Solução de problemas

A tabela a seguir lista alguns dos problemas mais comuns encontrados ao projetar uma DSL, junto com as sugestões para sua solução. Mais recomendações estão disponíveis no Fórum de Extensibilidade das Ferramentas de Visualização.

Problema Sugestão
As alterações feitas no arquivo de Definição de DSL não surtiram efeito. Clique em Transformar Todos os Modelos na barra de ferramentas acima do Gerenciador de Soluções e recompile a solução.
As formas mostram o nome de um decorador em vez do valor de propriedade. Configure o mapeamento do decorador. No diagrama de Definição de DSL, clique no mapa do elemento do diagrama, que é a linha cinza entre a classe de domínio e a classe de forma.

Abra a janela Detalhes de DSL. Se não for possível vê-la, no menu Exibir, aponte para Outras Janelas e clique em Detalhes de DSL.

Clique na guia Mapas do Decorador. Selecione o nome do decorador. Certifique-se de que a caixa ao lado esteja marcada. Em Exibir propriedade, selecione o nome de uma propriedade de domínio.

Para obter mais informações, consulte Formas no diagrama.
Não consigo adicionar uma coleção no Gerenciador de DSL. Por exemplo, quando clico com o botão direito do mouse em Ferramentas, não encontro o comando "Adicionar Ferramenta" no menu.

No gerenciador de minha DSL, não consigo adicionar um elemento à lista.
Clique com o botão direito do mouse no item acima do nó ao qual você está tentando adicionar elementos. Quando desejar adicionar elementos a uma lista, o comando Adicionar não estará no nó da lista, mas em seu proprietário.
Criei uma classe de domínio, mas não consigo criar instâncias no gerenciador de linguagens. Cada classe de domínio, exceto a raiz, deve ser o destino de uma relação de incorporação.
No gerenciador de minha DSL, os elementos são mostrados somente com seus nomes de tipos. Na Definição de DSL, selecione uma propriedade de domínio da classe e, na janela Propriedades, defina É Nome de Elemento como true.
Minha DSL sempre é aberta no editor XML. Isso pode ocorrer em função de um erro durante a leitura do arquivo. No entanto, mesmo após a correção desse erro, você deve redefinir explicitamente o editor para que seja o designer de DSL.

Clique com o botão direito do mouse no item do projeto, clique em Abrir com e selecione YourLanguageDesignerDesigner (Padrão).
A caixa de ferramentas de minha DSL não aparece após a mudança de nomes do assembly. Inspecione e atualize DslPackage\GeneratedCode\Package.tt. Para obter mais informações, consulte Como alterar o namespace de uma linguagem Domain-Specific.
A caixa de ferramentas de minha DSL não aparece, mas não alterei o nome do assembly.

Ou, uma caixa de mensagens aparece relatando a falha ao carregar uma extensão.
Redefina a instância experimental e recompile sua solução.

1. No menu Iniciar do Windows, em Todos os Programas, expanda o SDK do Visual Studio, em seguida, Ferramentas e clique em Redefinir a Instância Experimental do Microsoft Visual Studio.
2. No menu Compilar, clique em Recompilar Solução.