26 May 2006

DSL Tools for VS2005

This is a guide for Building a DSL Designer using the DSL Tools for VS2005.

Pre-requisites:

These components must be intalled:

  • Visual Studio 2005
  • Visual Studio 2005 SDK
  • DSL Tools for Visual Studio 2005

1. Create a new project in VS2005

The project template must be: Other Project Types -> Extensibility -> Domain Specific Language Designer.

Choose a template for the designer.

Note that VS has created a solution with 2 projects: Designer and DomainModel.

A DSL Designer consists of 3 components:

1. Domain elements (Domain Model)
2. Notational elements
3. Mapping between Domain and Notational elements

2. The Domain Model

The Domain Model is in the DomainModel.dsldm in the DomainModel Project. You can edit it by gragging and dropping the Domain Model Designer Tools of the Toolbox.

The Model contains classes and relationships. Classes may contain value properties.

3. The Notation

The Notation is represented in an xml file. The default description is in the file Designer.dsldd in the Designer Project.

The notation can include shapes which appear in the toolbox and can be dragged onto the design surface, connector for the shapes, etc.

4. Domain-Notation Mapping

This is also defined in the dsldd file. In general the mapping is between shapes and connector lines to classes and relationships respectively. So when a user creates shapes and connectors in the designer he also creates the classes and relationships in the domain.

5. Generate code and build

Click on the "Transform All Templates" button in the Solution Explorer Toolbar.
Build the solution.
Press Ctrl+F5 to run the designer.

6. Consuming the DSL

Templates consist of some directives followed by a mixture of literal blocks and control blocks. Literal blocks are just plain text in the template that you want to pass straight through to the output. Control blocks are things with some kind of <# #> marker around them.

The content of these blocks in your template contributes to a class which the templating system generates. This class derives from the abstract class Microsoft.VisualStudio.TextTemplating.TextTransformation and overrides the abstract method TransformText which, when executed, writes out the desired output of the transformation of the template. If you do nothing else in your template, this method will write out all of the text in literal blocks by simply writing out the raw text using a simple WriteLine()-style statement. The base class provides this WriteLine method (in various flavors) as well as Error and Warning methods that you can use in your custom template code.

7. Deployment

Add a Setup package to build a deployable designer.

DSL - A first approach to.

This is a summary of the Martin Fowler's article on Language Workbenches: The Killer-App for Domain Specific Languages? which I have recently read and found very interesting.

Terminology

Language Workbench: IDE tools to help Language Oriented Programming.

Language Oriented Programming: a style of development which operates about the idea of building software around a set of Domain Specific Languages.

Domain Specific Language (DSL): Limited form of computer language designed for a specific class of problems.


DSL

Imagine you build a class library to solve some particular problem and that the objects involved are parameterizable. So, you need a first step to set up configuration and wire up composite objects before putting them to do the work.

When building this kind of class library, there is a marked distinction between the abstraction itself and the configuration. The abstraction may be reusable and less often to change, while the configuration tends to be specific, more simple, and likely to change more often.

This leads to the idea of putting the configuration out of the code, for example, in xml files or in some custom syntax file (what may be more readily). The structure of this configuration, the mapping with the objects in the abstraction, the parameters, etc, are nothing but a kind of Domain Specific Language, a very small programming language, suitable for the only purpose of solving some specific problem.

If we leave the configuration in the code, instead of moving it to a configuration file, we still have a case of DSL, a DSL embedded in the host language. So here comes the distinction between internal and external DSL.

External DSL: DSL written in a different language than the main language of an application.

Internal DSL: DSL written in the same language of the main language of an application.

Language Oriented Programming

Language oriented programming is about describing a system through multiple DSLs. It does not have to be a black or white thing; you can represent little or a lot of functionality of your system in DSLs.

Pros and Cons of Language Oriented Programming

External DSL

Pros

Cons

  • Parameters can be changed without recompiling. Evaluated at runtime.
  • Format / grammar free.
  • A translator needs to be built.
  • Lack of symbolic integration.
  • Refactoring will not propagate to the DSL.
  • Lack of sophisticated editor.
  • Language cacophony: a new language must be learned.
  • Difficulty of designing DSLs.

Internal DSL

Pros

Cons

  • Symbolic Integration.
  • Host language IDE can be used.
  • Easy refactoring.
  • Sophisticated editors.

  • Recompilation required when making changes (in most languages).
  • Format / grammar free.

Language Workbenches

Language Workbenches are complex tools that help implementing DSLs. They are based on the same model as post-IntelliJ IDEs, which consists of having four different representations of the code:

Abstract representation: In-memory representation. Helps with things like name completion and refactoring. It is the key persistent source that you manipulate (through the editable representation). It can persist incomplete or contradictory information.

Editable representation: Projection of the abstract representation in order to edit it. It does not have to be complete. There can be multiple projections, one for each aspect.

Storage representation: Serialization of the abstract representation, often as XML.

Executable representation: The CLR byte code. A code generator turns the abstract representation into the executable representation.

So, when defining a new DSL you need to:

  • Define the abstract syntax, the schema of the abstract representation.
  • Define an editor to let people manipulate the abstract representation through a projection.
  • Define a generator to translate the abstract representation into an executable representation. In practice the generator defines the semantics of the DSL.

04 May 2006

Configuration Files & NUnit

When using an application configuration file (App.config) in a nunit library application project, the following post build event is needed to copy the config file to the target directory:
copy "$(ProjectDir)App.config" "$(TargetPath).config"
Once this is done, we can access any configuration item through:
System.Configuration.ConfigurationSettings.AppSettings["myConfigItem"]