Para crear un nuevo Domain Specific Language: Crear nuevo proyecto: Archivo -> Nuevo -> Proyecto
Otros Tipos de Proyecto -> Extensibilidad
-> Domain Specific Language Designer
Poner nombre al proyecto
- Poner nombre de Compañía
- Dejar el default de Strong Name Key File
- Revisar y hacer clic en Finalizar si todo es correcto
Como resultado del proceso que hemos seguido se obtiene un lenguaje de ejemplo. Le borraremos para ilustrar paso a paso la forma de construir el DSL.
Borrar todas las clases de dominio del
lenguaje mínimo (en Classes and Relationships), excepto la principal (la
principal es la que está en la raíz del modelo), lo mismo con los Diagram
Elements borrar todas excepto la que es de tipo Diagram (que es la principal)
- Cambiar nombre a Clase Principal y al Diagrama Principal ambos en propiedad Name (seleccionamos la clase y en la ventana properties hacemos los cambios),
- Al dar Validate All (botón derecho del ratón sobre el área de DslDefinition.dsl y valídate all), genera error.
- Borrar las tools asociadas a los nodos del lenguaje recién eliminado (ir a la ventana DSL Explorer, Editor, Toolbox Tabs, DSLPagsWeb, Tools)
- Otra vez Validate All y listo, se puede hacer un Transform templates (Explorador de soluciones, botón Transform All Templates), e iniciar depuración (Menú Depurar, Iniciar Depuración). Habrá un lenguaje vacío
COMENZAR LA REALIZACIÓN DEL domain model
Agregar del cuadro de htas: Named Domain Class y cambiar su nombre
a Pagina. Así mismo, arrastrar Embedding
Relationship de SitioWeb a Pagina
haciendo botón derecho sobre Pagina (la
ligada), seleccionar Bring Tree Here
para evitar una doble ilustración
Agregar una nueva propiedad a la página (botón
derecho sobre la leyenda Domain Properties, add new domain property), a la que
llamaremos Descripcion empleando la ventana properties
Cambiar nombre a relación de SitioWebHas hacia SitioTienePags
Cambiar nombre del Source Role (a la izquierda
de la relación SitioTienePags, arriba de la multiplicidad) a Pags, para ello, seleccionar el rol y
en la ventana propiedades cambiar las propiedades: Name y PropertyName. Al
target role (a la derecha de la relación SitioTienePags, arriba de la
multiplicidad), nombrarlo Sitio del
mismo modo. La multiplicidad no se cambió
En el área de diseño, botón derecho -> Validate All. Transformar templates para probar que todo vaya bien
Agregar una Reference Relationship (tomada del
cuadro de htas) partiendo de Pagina y llegando a Pagina
Renombrar roles, el source (a la izq de la relación) como: PagDest y el target (a la derecha de la
relación) como PagOri. Rrecordar hacerlo
tanto en property name, como en name. La relación renombrarla a PagEnlacePag. La multiplicidad se
conserva.
Validate All-> Transform Templates ->
Depurar –>Iniciar depuración
Vamos a tener un IDE del DSL pero sin
herramientas
Cerrar la ventana Visual Studio de depuración
Agregar (del cuadro de herramientas de Visual
Studio) un Geometry Shape, cambiarle
el nombre a PagShape,
Después agregar un Diagram Element Map entre la clase Pagina y el elemento de diagrama
PagShape
Agregar un decorador a PagShape con botón
derecho Add New Text Decorator
y llamarlo NameDecorator
Seccionar el map de diagrama
Activar Ver->Otras ventanas -> DSL
Details e ir a pestaña Decorator Maps, para indicar que NameDecorator (activar casilla) está relacionado en el combobox Display property con
Name, es decir, ese decorador va a
estar enlazado con la propiedad name
que va a obtener del modelo
Crear a partir del cuadro de htas. un Connector, y renombrarlo como LinkShape,
Enseguida agregar un DiagramElementMap partiendo de la relación de referencia llamada PagEnlacePag hasta LinkShape
Agregar htas en DSL Explorer -> Editor -> Toolbox Tabs -> DSL Pags Web ->
boton derecho
Agregar un ElementTool y un ConnectionTool
Seleccionar el ElementTool1 agregado y en la
ventana de propiedades modificar las props:
Class –> debe apuntar a la clase que se va
a modelar, en este caso Pagina
Name -> El nombre de la tool (Pagina)
Caption -> Lo que va a decir en el cuadro
de htas (Crear una Pagina)
Toolbox icon-> directorio de proyecto, DSL\Resources\ExampleShapeToolBitmap.bmp
Tooltip -> Para las pistas de ayuda
Seleccionar el ConnectionTool1 agregado y en
la ventana de propiedades modificar las props:
Connection Builder –> debe apuntar a la
clase relación que se va a modelar, en este caso PagEnlacePag
Name -> Conexion
Caption -> Lo que va a decir en el cuadro
de htas (crear enlace)
Toolbox icon-> directorio de proyecto, DSL\
Resources\ExampleConnectorToolBitmap.bmp
Tooltip -> Para la ayuda
Validate
All -> Transform Templates -> Start Debug F5
Por default con el proyecto se crean dos archivos de ejemplo Test y Sample, se puede hacer doble click en ellos para abrirlos y a continuación modificarlos agregando nuevas clases de dominio y enlazarlas con relaciones.
En ocasiones no carga el panel de herramientas de nuestro DSL, eso se debe a que el modo de depuración está usando una "imágen" de proyecto no actualizada con los últimos cambios a la configuración, si ese es el caso, cerrar depuración, ir al menú Build, hacer un Rebuild, nuevamente Transform All Templates y volver a arrancer el modo de depuración de nuestro DSL.
El siguiente es un programa válido
Generar -> Volver a generar solucion ->
Depurar -> Iniciar depuracion
CREACION DE LAS PLANTILLAS GENERADORAS DE
CODIGO
- Asegurarnos que estamos en el modo de depuración, es decir, ahorita tenemos el nuevo lenguaje en ejecución
Seleccionar Explorador de soluciones ->
(botón derecho del ratón sobre debugging) ->Agregar -> Nuevo elemento
Escoger archivo de texto y renombrar a
plantilla.generador
Seleccionar en el Explorador de soluciones el
archivo recién generado: Plantilla.generador
Y establecer la propiedad herramienta personalizada en propiedades:
TextTemplatingFileGenerator
Agregar el código que sigue al archivo
plantilla.generador (las dos primeras
instrucciones las debe llevar toda plantilla)
<#@ template
inherits=
"Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
<#@ DSLPagsWeb
processor="DSLPagsWebDirectiveProcessor"
requires="fileName='Test.dslpw'"
#>
Filename es el archivo que contiene el modelo(programa
del nuevo lenguaje)
NOTESE EL NOMBRE DEL DSL INDICADO
AL CREAR EL LENGUAJE
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
class Programitas
{
public
void crear()
{
TextWriter tw;
string a;
Mediante
un foreach haremos un recorrido sobre el conjunto de paginas
Pagina es la clase del dominio que modela las
páginas web
SitioWeb es la clase principal (la
raiz) de las clases del dominio
(classes and relationships)
Pags es el source role de la clase
raiz
<# foreach(Pagina
p in this.SitioWeb.Pags)
{
#>
LA PROPIEDAD DEL OBJETO
Console.WriteLine("Creando
archivo: <#=p.Name#>.html");
TextWriter tw = new StreamWriter("<#=p.Name#>.html");
tw.WriteLine("<html>
hola que tal, estoy en archivo <#=p.Name#>.html </html>");
tw.Close();
Console.WriteLine("Se ha generado el
archivo <#=p.Name#>.html...");
a = Console.ReadLine();
<#
}
#>
}
}
Otro ejemplo de generación de código, para
otro lenguajes es:
<#@ template
inherits="Microsoft.VisualStudio.TextTemplating.VSHost.ModelingTextTransformation"#>
<#@ output extension=".txt" #>
<#@ PLenguajePaginasWeb
processor="PLenguajePaginasWebDirectiveProcessor"
requires="fileName='Test2.dslwebpages'" #>
<#
foreach(PaginaWWW pag in this.SitioTec.webpages)
{
#>
//----------------- <#= pag.Name #>
--------------------
<html>
<body>
<bold> Esta es la página de:
<#= pag.Name #> </bold>
<# //verifica que exista un
encabezado
if (pag.heads2!=null)
{ #>
<h1> <#= pag.heads2.Text #> </h1>
<# } #>
<#
foreach(PaginaWWW pagdest in pag.destino)
{ #>
<A href="<#=pagdest.Name#>.html">Ir a pag <#=pagdest.Name#> </A>
<#
} #>
</body>
</html>
//----------------------------------------------------
<#
}
#>
Donde se verifica que exista o no un elemento
(if pag.heads2!=null), cuando la multiplicidad es 0..1 no se genera un arreglo y por tanto debemos verificar si
existe o no un elemento.
Para invocar la ejecución de la plantilla
Dar botón
derecho del ratón sobre el nombre de la plantilla.generador, en el explorador
de soluciones, y hacer clic en Ejecutar Herramienta Personalizada
Abajo del nombre de la plantilla, en el
Explorador de Soluciones, aparece el nombre de un archivo, que si no indicamos
otra cosa, se llamará igual que el nombre de la plantilla pero con la extensión
cs (c Sharp), la extensión se puede indicar incluyendo una macroinstrucción en
la plantilla. En dicho archivo estará el código generado
El código generado es: