Describing Domain Concepts
The first thing you have to do when building a Domain-specific Language is make sure you understand the problem that you are trying to model exactly and thoroughly. In our example this is service contracts and its relation to WSDL. Let's have a quick look at some concepts in the Domain-specific Language and describe them in a little more detail.
Let's start with the ServiceInterface
concept, which is the high-level abstraction of the service contract. The ServiceInterface describes which operations and accompanying messages are exposed by the service. It's the ServiceInterface that actually describes what can be done with the service.
Next we have the ServiceOperation
concept, which defines an operation in the ServiceInterface. The ServiceOperation describes the message exchange patterns and the accompanying messages for the operation. In other words, it defines the input and optional output message for the operation. (The sample DSL only supports two basic message exchange patterns from WSDL: one-way and request-response.) This leaves us with the next concept, the Message
. A Message is a placeholder for the data structures used in the ServiceOperations. In real life, Messages are often described in an XSD schema and referenced in WSDL. Since the Message holds the definition of the data structures, this is where the concept of a DataContract
comes in. A DataContract represents the data structure itselfthink of it as the data on the wire. Just like Messages, you often define DataContracts in an XSD schema. A Message consists of one or more DataContracts. Please note that the DataContract concept in our example Domain-specific Language doesn't necessarily relate to the Windows Communication Foundation DataContract
|Figure 3. Solution Explorer View: Here are the initial solution projects for building a custom DSL.|
Another concept that is embedded in the Message is the MessageHeader
. You use the MessageHeader to store out-of-band data that has to flow with the message. For example, you might have user credentials that need to travel with the message to the ServiceOperation.
How did we find the concepts in our service contract domain? We had a close look at elements that can be identified in WSDL and made sure we understood their purpose. Remember that in our example, WSDL and service contracts are
the problem domain. After we looked at the elements, we tried to describe them at a higher abstraction level that makes sense to developers and architects who design and build services.
It is exactly this step in the approach that is extremely important when starting to build your own domain-specific language: Don't start modeling before you know what you are trying to solve.
Table 1 gives you an overview of the concepts that exist in our service description language together with their WSDL counterparts. It's eventually the WSDL part that gets generated out of the domain-specific language.
Table 1. The table shows WSDL concepts in the sample DSL.
The next step in building a domain-specific language is describing the artifact(s) you are planning to use in your domain-specific language. Of course, you also need good knowledge of the artifacts to be able to describe the domain concepts in the first step, but in this step you formalize the artifacts in more detail. For example, when you think a piece of C# code is the artifact of your domain-specific language, you write a first version of this C# code in this step. The reason for this is that you can use this formalized artifact to validate the domain concepts you defined in the first step. For our example we just had a close look at the WSDL specification and the WS-I BP 1.1
. An example of a valid and proven WSDL was enough to act as our formalized artifact. Remember that artifacts or the number of artifacts change during the development phase of your domain-specific language.
Building Domain Models
Based on a clear understanding of the problem domain and the knowledge of what an initial version of our artifacts looks like, let's really start building our domain-specific language. To do this you need Visual Studio 2005 Team System and the Microsoft DSL Tools installed on your machine.
Note that any code or screenshots in this article are based on the November 2005 CTP release of the DSL Tools. Although significant changes are expected in the final release of the DSL Tools, this should have little impact on the content of this article because we don't provide step-by-step guidance for how to build a domain-specific language with the DSL Tools.
To get started you first have to create a new solution within Visual Studio that is based on the "Domain-specific Language" template. A wizard will guide you through this process and will ask some details like name, namespace, and file extension for your language. After you've completed the wizard, Visual Studio will load with a solution that you can build your domain-specific language in.
|Figure 4. Sample DSL Domain Model: Here's a graphical version of the domain model for the sample DSL.|
We will use the domain model designer within Visual Studio to graphically build the domain model for our language. Figure 4
shows the domain model of the Service Description Language. The current state of the domain model only reflects the concepts we need for describing the service contract itself. Of course, this domain model can evolve over time to cover more service-related topics.
As you will see when you try this yourself, creating a domain model is just a matter of dragging elements from the toolbox to the designer area. In this step, we'll represent the domain concepts that we defined earlier for our domain-specific language as classes in the domain model. You can add custom properties to classes and make them participate in relationships. As the name probably implies, you can use a Relationship
to relate domain concepts with each other.
shows that we created a relationship from the ServiceOperation concept to the Message concept in our service description language. We also created relationships from the Message concept to the DataContract and MessageHeader concept. If you have a close look at the latter relationships in the screenshot you can see they are represented by a solid line. The relationship between the ServiceOperation and Message concepts is represented by a dotted line. The difference between both is caused by the type of relationships we used in both cases.
The dotted line represents a "reference relationship" between ServiceOperation and Message. In plain English, this relation means a ServiceOperation "knows about" or "is using" a Message. The solid line represents an "embedding relationship" between a Message and a DataContract and or MessageHeader. This means that the DataContract (or MessageHeader) is part of the Message. In other words a Message consists of a DataContract and MessageHeader. As you will see later on in this article, the difference between the two types of relationships will also show up in the designer for the DSL.
As you will notice when experimenting with the DSL Tools, the domain model is persisted as XML and is stored in a file with extension .dsld
and can be found in the DomainModel
project in the Visual Studio solution. This will change in the RTM release of the DSL Tools.
Without going into too much detail, you saw how to translate the identified domain concepts into a domain model within the DSL Tools. Let's look at how to continue building our language.
Building a Designer
Now let's build a designer for the language. As we said earlier in this article, the graphical designer does not make any language a domain-specific language, but since providing a graphical designer for a domain-specific language is part of the DSL Tools we will be more than happy to use this feature.
|Figure 5: Designer Markup: The figure shows an XML snippet of the designer markup.|
Just like the definition of the domain model, the designer definition is stored as an XML file with a .dsldd
extension and can be found in the Designer
project of the Visual Studio solution. Unfortunately it isn't possible to graphically maintain this designer definition in the November CTP of the DSL Tools. Also, there is no strict relation between the domain model definition and the designer definition. Therefore you have to make sure you keep both files in sync by hand, which can be a tedious task. All of this will change in the RTM release of the DSL Tools.
shows a snippet of the designer definition file where we describe the MessageShape
in the language. The MessageShape is the graphical representation of the Message concept in the service description language. As you can see, the MessageShape is a so-called CompartmentShape
and also holds the definition for the DataContractShape
and the MessageHeaderShape
(think of the embedding relation between the Message, DataContract, and MessageHeaders concepts). Also note that we added two extra ShapeIcon
elements, named RightArrow
, to the definition of the MessageShape. We'll explain a little later why we needed to do that.