Escrever código para personalizar uma linguagem específica de domínio
Esta seção mostra como usar código personalizado para acessar, modificar ou criar um modelo em uma DSL (linguagem específica do domínio).
Contexto para escrever código para uma DSL
Há vários contextos em que você pode escrever código que funciona com uma DSL:
Comandos personalizados. Você pode criar um comando que os usuários podem invocar clicando com o botão direito do mouse no diagrama e que pode modificar o modelo. Para obter mais informações, consulte Como adicionar um comando ao menu de atalho.
Validação. Você pode escrever um código que verifica se o modelo está no estado correto. Para obter mais informações, confira Validação em uma linguagem específica de domínio.
Substituir o comportamento padrão. Você pode modificar muitos aspectos do código gerado com base em DslDefinition.dsl. Para obter mais informações, consulte Substituir e estender as classes geradas.
Transformação de texto. Você pode escrever modelos de texto que contêm código que acessa um modelo e gera um arquivo de texto, por exemplo, para gerar código de programa. Para obter mais informações, confira Gerar código de uma linguagem específica de domínio.
Outras extensões do Visual Studio. Você pode escrever extensões VSIX separadas que leem e modificam modelos. Para obter mais informações, confira Como abrir um modelo do arquivo no código do programa
Repositório na memória
As instâncias das classes que você define em DslDefinition.dsl são mantidas em uma estrutura de dados chamada IMS (repositório na memória) ou Repositório. As classes que você define em uma DSL sempre usam um Repositório como argumento para o construtor. Por exemplo, se a DSL definir uma classe chamada Example
:
Example element = new Example (theStore);
Manter objetos no repositório, em vez de apenas como objetos comuns, oferece vários benefícios.
Transações. Você pode agrupar uma série de alterações relacionadas em uma transação:
using (Transaction t = store.TransactionManager.BeginTransaction("updates")) { // make several changes to Store elements here t.Commit(); }
Se ocorrer uma exceção durante as alterações, de modo que o
Commit()
final não seja executado, o repositório será redefinido para o estado anterior. Essa abordagem ajuda você a garantir que erros não deixem o modelo em um estado inconsistente. Para obter mais informações, consulte Navegar e atualizar um modelo no código do programa.Relações binárias. Se você definir uma relação entre duas classes, as instâncias nas duas extremidades terão uma propriedade que navega para a outra extremidade. As duas extremidades sempre estão sincronizadas. Por exemplo, se você definir uma relação de paternidade com funções chamadas Pais e Filhos, poderá escrever:
John.Children.Add(Mary)
Agora, estas duas expressões são verdadeiras:
John.Children.Contains(Mary)
Mary.Parents.Contains(John)
Você também pode obter o mesmo efeito escrevendo:
Mary.Parents.Add(John)
Para obter mais informações, consulte Navegar e atualizar um modelo no código do programa.
Regras e eventos. Você pode definir regras que são acionadas sempre que são feitas alterações especificadas. As regras são usadas, por exemplo, para manter as formas no diagrama atualizadas com os elementos de modelo que elas apresentam. Para obter mais informações, confira Responder a alterações e propagá-las.
Serialização. O repositório proporciona uma maneira padrão de serializar os objetos que ele contém em um arquivo. Você pode personalizar as regras para serializar e desserializar. Para obter mais informações, consulte Personalizando o armazenamento de arquivos e a serialização XML.