Dentro del SDK de Visual Studio (a partir de la versión 2005), se encuentran las DSL Tools, que permiten la definición de los elementos de la DSL, la creación de diseñadores gráficos y la generación automática de código usando una notación bastante sencilla, basada en plantillas, que pueden ser escritas en C# o en VB.net.
Está bien, parece interesante, pero cómo se hace esto?
Lo primero, es la instalación del SDK de la versión correspondiente a Visual Studio que tienes instalada.
Para crear un DSL debemos crear un proyecto de tipo Doman-Specific Languaje Designer
Al crear la solución, se mostrará un asistente que nos guiará en la creación del proyecto. Existen plantillas, que contienen elementos del dominio y diseñadores predefinidos, en las que podemos basar nuestro DSL.
Los posteriores pasos del asistente son triviales. Piden información acerca del nombre del proyecto, la compañía, etc.
Para el ejemplo, seleccionaremos la plantilla MinimalLanguaje.
Finalizado el asistente, se crean en la solución, dos proyectos: Dsl y DslPackage.
Dentro de la solución, en el proyecto DSL encontraremos estos elementos:
Al archivo DslDefinition, en el que definiremos todas las piezas de nuestro puzle.
El panel DslExplorer, que nos mostrará, de una manera organizada, los elementos, y la lógica que definirá el comportamiento de nuestro Dsl.
El panel DSL Details, que nos informará de algunas propiedades del elemento DSL seleccionado en diseñador DSL.
La Toolbox, en la que encontraremos los elementos que podemos arrastrar al diseñador.
Una cosa realmente curiosa, es que la herramienta que estamos utilizando para crear nuestro DSL, es decir el "DSL Designer" de Visual Studio es un DSL, es decir, un lenguaje visual a partir del cual crearemos en un lenguaje no específico, la solución a nuestro problema especifico. Simplemente, impresionante.
Como siguientes pasos para la demo, realizar las siguientes acciones:
Eliminar los elementos: ExampleElement, ExampleShape y ExampleConnector
Añadir, desde la Toolbox un y llamarlo StoredProcedure
Añadir otro Named Domain Class y llamarlo Parameter
Añadir otro Named Domain Class y llamarlo Resulset
Añadir otro Named Domain Class y llamarlo Field
A continuación, los siguientes pasos:
Conectar ExampleModel con StoredProcedure mediante un
Conectar StoredProcedure con Resulset mediante un Embedding RelationShip
Conectar StoredProcedure con Parameter mediante un Embedding RelationShip
Conectar Resulset con Field mediante un Embedding RelationShip
A continuación, más pasos:
Añadir un y llamarlo StoredProcedureCompartmentShape.
Botón derecho sobre Decorators y Add new Text Decorator.
Botón derecho sobre Compartments y Add new Compartment.
Editar las propiedades de Compartment1 y establecer la propiedad Title a “Parameters”.
Conectar StoredProcedure con StoredProcedureCompartmentShape mediante un Diagram Element Map.
Añadir un CompartmentShape y llamarlo ResulsetCompartmentShape.
Botón derecho sobre Decorators y Add new Text Decorator.
Botón derecho sobre Compartments y Add new Compartment.
Editar las propiedades de Compartment1 y establecer la propiedad Title a “Fields”.
Añadir un y unirlo mediante un con la relación que hay entre StoredProcedure y Resulset, es decir, StoredProcedureHasResulset.
Doble Click en la Línea que une El StoredProcedureCompartmentShape y el StoredProcedure.
En la pestaña DSL Details, seleccionar, la pestaña Decorator Maps y en Decorators, marcar el check TextDecorator1.
En el drop Display Property que aparece más a la derecha, seleccionar la propiedad Name.
A continuación, cambiar a la pestaña Compartment Maps.
Seleccionar el check Compartment1 y en el TextBox de la derecha “Displayed elements collection path:” escribir:
StoredProcedureHasParameters.Parameters/!Parameter
En el drop “Display property:” seleccionar la propiedad Name.
Luego, exactamente lo mismo para la Línea que une El ResulsetCompartmentShape y el StoredProcedure.
En la pestaña Compartment Maps, el texto de “Displayed elements collection path:” debe ser:
ResulsetHasFields.Fields/!Field
Finalmente, en el panel DSL Explorer, en el nodo SPDSL (Dsl)EditorToolbox TabsSPDSLTools
Eliminar ExampleElement y ExampleRelationShip
A continuación, click con el botón derecho sobre SPDSL Add new Element Tool
Editar las propiedades del nuevo nodo:
Class = StoredProcedure
Name = StoredProcedureTool
Toolbox Icon = Seleccionar un icono. (Se pueden agregar más iconos añadiendo imágenes a la carpeta Resources del proyecto en el Solution Explorer)
Nuevamente, en el DSL Explorer, botón derecho sobre SPDSL, Add new Connection Builder.
Luego, botón derecho sobre el nuevo nodo, Add new Connection Builder Directive
Seleccionar el nuevo nodo, y en el panel DSL Details…
Seleccionar en RelationShip la relación StoredProcedureHasResulset
En Source role directives, seleccionar StoredProcedure y en Target role directives, seleccionar Resulset.
Y ya por último, nuevamente en el DSL Explorer…
Botón derecho en SPDSL, Add new Connection Tool.
Editar las propiedades del nuevo nodo, y establecer el Connection Builder, el Name y el Tool Box Icon.
Ya ya, guardar todo, click en el botón Transform All Templates del Solution Explorer y F5
Si todo ha ido bien, el resultado debe ser este:
Y la definición del DSL debe quedar así:
To be continued.
En la siguiente entrega, intentaré mostrar como agregar propiedades a los elementos del dominio, y hacer que las cajitas del diagrama sean más bonitas. Pero vamos, visto esto, todo lo que viene a continuación es muy sencillo.
Qué son exactamente los DSL y qué posibilidades nos ofrecen? En su definición más generalista