Tuesday, December 06, 2005

Some days ago I received an email of somebody asking me if I am (still) using T4 templates within the DSL we are building. After reading some of my latest post he got the idea that a lot of the features we are building aren’t implemented in Text templates (T4). He asked me if there is a special reason for that and if I think the T4 templates are useful enough for writing (parts of) your DSL.

 

Actually it is true that a lot of the things I am currently working on is implemented in pure C# code and is hooked into the diagram itself by using techniques described in earlier posts. For me this works just great.

 

The thing I like about integrating as many features as possible directly in the diagram itself is that it requires no user actions (selecting menu items) to “execute the feature”. For example, in our DSL you don’t have to select a menu item to translate a Service that is modelled in our Designer into WSDL. This is done on the fly whenever a change is made in the designer and the diagram is still a valid representation of a Service. All of this is done by events that get triggered “automatically” through the designer. Another option was to implement the WSDL generation into T4 templates and let the user trigger the execution of the T4 template through a menu item.

 

It’s not that I don’t like writing T4 templates! Actually I do like the templates. I have to admit that there are some improvements possible in the “writing experiences” of these templates but I am sure this will improve in future builds of the DSL Tools. I can imagine that we will use the T4 templates for some other artifacts that get generated out of our domain model. To be honest, the WSDL generation for our DSL is besides the “pure C#” version also available in a T4 template. Translating the “pure C#” version into a T4 template (and vice versa) was done in a few minutes.

 

So, to answer the question in the email that starts me writing this post. A lot of the functionality in our DSL is built in “pure C#” directly hooked into the diagram, but that doesn’t mean that I don’t like T4 templates or think they are not useful! In fact, they will be part of our DSL. I think you have to find out for yourself what features and/or customizations you need in your DSL and what can be best implemented in pure C# and what can be best implemented in T4 templates.

 

I noticed that George Mathew (team member DSL Tools) wrote one of his first posts on his blog about new features in the Text Templates (T4) of the DSL Tools. Maybe he (or other team members) has some thoughts or better explanation on when to use the T4 templates and when to implement things directly into the designer or diagram?

 

 

posted on 12/6/2005 9:48:53 PM UTC  #   
 Monday, December 05, 2005

In an earlier post I mentioned I am using the “OnTransactionCommiting” on the Diagram class to implement some logic (generating WSDL) for the DSL we are writing. My remark at that point was that the event is triggered a lot and therefore might not be the best place to implement time consuming logic. At that point I didn’t pay a lot of attention to the “TransactionCommitEventArgs” parameter of the event. After some further investigation I found out that the “Transaction” (that can be reached through the TransactionCommitedEventArgs) has a logical name that “indicates” what is happening in the diagram and what (user) action triggered this event.

 

For example, when changing the value of a property named “WSDLDescription” in the diagram, the name of the Transaction is “Set WSDLDescription”, when first loading a diagram the name of the Transaction is “LoadDocData”, etc. The code snippet below gives you an idea how to limit unnecessary (custom) code executions that you might implement in the “OnTransactionCommiting”.

 

public override void OnTransactionCommitting(TransactionCommitEventArgs e)
{
   base.OnTransactionCommitting(e);

   if ( e.Transaction.Name.ToUpper() == "SET WSDLDESCRIPTION")
   {

      //only execute in case of a change in the WSDLDescription property
      DoStuff();
   }
}

 

This actually means that I have much more control than I initially thought and therefore makes the “OnTransactionCommiting” a usefull event to implement some other logic too.

 

To be continued…

posted on 12/5/2005 7:14:04 PM UTC  #   
 Tuesday, November 22, 2005

One of the things I *really* want to implement for our DSL is “round tripping”. This means in my case, (at least) generate a “Service Description diagram” out of a valid WSDL file and visa versa.

 

Some weeks ago I already did an attempt in this direction but eventually I ran into problems with the serializer. As you can read in this post on the DSL forum the relations between concept got lost when trying to serialize (save to disk) the in-memory representation of the generated diagram. Probably this is caused by either a mistake on my side or a bug in the DSL Tools. Some days ago while playing with the propagation rules I found a way to make “round tripping” work in our DSL. Let me explain a little further.

 

I added a new property to the “Service” concept in the DSL, called “WsdlDescription”. This property represents a reference to a WSDL file describing the service. I added a new propagation rule that fires whenever the “WsdlDescription” property of the Service concept changes. This propagation rule, on its turn, fires a piece of code that parses the WSDL file (referenced by the “WsdlDescription” property) and generates a diagram out of this. With this code in place I can generate a diagram out of a WSDL file by simply creating a new empty diagram. To be more precise, adding a new item to the Visual Studio solution based on the “ServiceDescription” (name of the DSL) template. This results in an (valid) empty diagram. I can set the “WsdlDescription” property (service concept) in the empty diagram to reference a valid WSDL file and the magic happens, the diagram is generated! The advantage of this approach, compared to creating an empty diagram from scratch by using custom code, is that we can rely on the DSL Tools infra structure to properly initialize the diagram.

 

Of course you can find another “hook” to implement your round tripping code. This depends on the DSL you are building. For this moment, in our DSL, the propagation rule on this property does the trick.

 

Let’s have a look at some code. Below you see the code for the propagation rule that is defined for the “Service” concept in the model. First we try to cast the input parameter of the “ElementAttributeChanged” method to a “Service”. If that succeeds and the rule is fired because of a change in the “WsdlDescription” property we can continue. To create any new concepts in the diagram we need the “Store”. This can be seen as the in-  memory representation of the diagram. We can get this by using the “Store” property on the “Service”. Then we create a “ServiceInterface and ServiceOperation and register both elements under the Service by using the “ServiceArtifacts” relation. (To better understand the model of this DSL, have a look at the, slightly outdated, image of the domain model of the DSL). Finally we add the “ServiceOperation” as an “Operation” under the “ServiceInterface” and we are done. We now created two model elements and a relation between them in code. All displayed perfectly in the diagram.

 

[RuleOn(typeof(OurCompany.Design.ServiceDescription.DomainModel.Service),
                                                     FireTime
= TimeToFire.TopLevelCommit)]
    
public sealed class DomainModelServicePropertiesChangesRule : ChangeRule
    {
        
public override void ElementAttributeChanged(ElementAttributeChangedEventArgs e)
        {
            
            
// cast input parameter to Service element
            OurCompany.Design.ServiceDescription.DomainModel.Service service
=
                                 e.ModelElement
as OurCompany.Design.ServiceDescription.DomainModel.Service;
            
if (service != null)
            {

                
// only execute it when the rules is fired because of a change in the WsdlDescription property.
                
if (e.MetaAttribute.Id ==
                        OurCompany.Design.ServiceDescription.DomainModel.Service.WsdlDescriptionMetaAttributeGuid)
                {
                    
                    
// create new ServiceInterface. Use the store of the service
                    ServiceInterface serviceInterface
=                                                                 ServiceInterface.CreateServiceInterface(service.Store);
                    serviceInterface.Name
= "GeneratedInterface";
                    
                    
// add ServiceInterface as an ServiceArtifact of the service
                    service.ServiceArtifacts.Add(serviceInterface);

                    
// create new ServiceOperation. Use the store of the service
                    ServiceOperation serviceOperation
= ServiceOperation.CreateServiceOperation(service.Store);
                    serviceOperation.Name
= "GeneratedServiceOperation";

                    
// add ServiceOperation as an ServiceArtifact of the service
                    service.ServiceArtifacts.Add(serviceOperation);

                    
// add the relation from serviceInterface to serviceOperation
                    serviceInterface.ServiceOperation.Add(serviceOperation);
                }
            }


        }

    }




In the above code snippet all of the diagram generating is hard coded, this is, of course, just for this example. In my situation the hard coded stuff is replaced by some calls to helper functions that parse the WSDL and translate this back in a diagram.

 

To make sure the rules gets executed on changes in the Service concept we need to facilitate that it can be “picked up” by the “rule engine”. This is done by reflection; therefore we need the following code.

    // This class is reflected on to load rules dynamically.
    
// Add a variable for each custom rule.
    
internal static partial class GeneratedMetaModelTypes
    {
        
internal static Type DomainModelServicePropertiesChangesRule =
                                    
typeof(DomainModelServicePropertiesChangesRule);
    }

 

Now the diagram is generated out of the WSDL, we have to make sure the WSDL stays in synch with any changes that might be made in the diagram. It’s my intention to let this synchronisation magic happen automatically, so without any user actions (pressing menu options, etc.). To experiment with this I added the “synchronization logic” to the “OnTransactionCommiting” event of the diagram. As you can see in the code snippet below this is just a matter of overriding the “OnTransactionCommiting” method in a partial “ServiceDescriptionDiagram” class.

 

public partial class ServiceDescriptionDiagram
{
   public override void OnTransactionCommitting(TransactionCommitEventArgs e)
   {
      base.OnTransactionCommitting(e);

      //validate the diagram and execute synch code


   }

}

 

Although this works perfect I am not absolutely sure if this is the right place to implement this kind of logic. I noticed that the code gets fired a lot. Within this method I first validate the diagram to make sure there is enough information in the diagram to generate a valid WSDL file. If so, the generation (synchronisation) starts. I haven’t experienced any performance issues with this approach but maybe it is better to only synch when the diagram gets saved. I have to do some more investigation on this area.

 

To be continued….

 

posted on 11/22/2005 8:24:24 PM UTC  #   
 Sunday, November 20, 2005

 

The MessageHeader concept in our DSL has an attribute “SchemaLocation” (the same is true for Message and DataContract). This property is a reference to the XSD description of the MessageHeader. Another property of the Message concept is the “Namespace” property. The value of this property is used in the WSDL that is generated out of the Domain model of our DSL. In an attempt to make our DSL as user friendly as possible I decided to set the “Namespace” property automatically as soon as the “SchemaLocation” is populated.

 

To make this possible I wrote a propagation rule (one of the customization features of the DSL Tools) to make this happen.

 

Below you can see the code that is needed for a propagation rule. I stored this code in a separate .cs file in a folder called “custom” that I created in the designer project. The rule inherits from “ChangeRule”. The implementation isn’t that difficult (note: just demo code)

 

[RuleOn(typeof(OurCompany.Design.ServiceDescription.DomainModel.MessageHeader),
FireTime = TimeToFire.TopLevelCommit)]
public sealed class DomainModelMessageHeaderPropertiesChangesRule : ChangeRule
{
   public override void ElementAttributeChanged(ElementAttributeChangedEventArgs e)
   {
      // store the Namespace in
      string messageHeaderNamespace;


      OurCompany.Design.ServiceDescription.DomainModel.MessageHeader messageHeader =
      e.ModelElement as OurCompany.Design.ServiceDescription.DomainModel.MessageHeader;
      

      if (messageHeader != null)
      {
         if (e.MetaAttribute.Id ==
         OurCompany.Design.ServiceDescription.DomainModel.MessageHeader.SchemaLocationMetaAttributeGuid)
         {

            if (!String.IsNullOrEmpty(messageHeader.SchemaLocation))
            {

               // helper code to retrieve the Namespace from the XSD 
               ServiceDescriptionEngine.GetSchemasFromXsd(messageHeader.SchemaLocation, out messageHeaderNamespace);


               // set the value of the Namespace property 
               messageHeader.Namespace = messageHeaderNamespace;

            }

         }   

      }
}

}

 

 

Because the code that actually retrieves the “Namespace” out of the XSD file is stored in another assembly that isn’t part of the DSL assemblies, I had to add the assembly to the GAC to make it work.

 

To make sure the rule gets fired we need to add a variable to the “GeneratedMetaModelTypes” class. This class is reflected on to dynamically load rules. The variable is the reference to the new propagation rule described above. The following code snippet will do the trick.

 

Internal static partial class GeneratedMetaModelTypes
{
        
internal static Type DomainModelMessageHeaderPropertiesChangesRule =
                                    
typeof(DomainModelMessageHeaderPropertiesChangesRule);
}

 

As you can see in the image below (I know this image doesn’t prove a lot!) the “Namespace” property gets set after we populate the “SchemaLocation” property of the MessageHeader with a valid value.

To be continued...

posted on 11/20/2005 8:12:43 PM UTC  #   
 Friday, November 18, 2005

Because we made some good progress with building the core functionality of our DSL I decided to spend some time on the customization options of the DSL Toolkit.

I tried some of the customizations described in this document that can be found on the DSL Tools forum and also implemented the “ToolTipText” for all of the shapes and connectors by using the code that is described in this post of Pedro Silva.

Another thing that I found was necessary was changing the color scheme of the Shapes. I decided to use some RGB colors and found out that using an “RGB color code” in the designer.dlsdd file isn't an option. It wasn't too hard to found out how this can be achieved by writing some lines of custom code. As you can see in the code snippet below it is just a matter of overriding the FillColor property in a partial class for the Shape.

public partial class ServiceOperationShape
{

    
public override Color FillColor
    {
        get
        {
            
return Color.FromArgb(132, 150, 172); 
        }
            
    }

}

The Message concept in our DSL is holding an embedding relation for the DataContract and MessageHeader concept. Therefore our MessageShape is a compartment shape this means for these two compartments there isn’t a possibility to override the FillColor property in a partial class.

 

We had to find another way to changes the color. It turns out that compartments can be reached in custom code by using the “compartmentDescriptions” collection on the parent shape. As you can see in the code snippet below I used the “OnInitialized” of the MessageShape (parent) to set the “TitleFillColor” property of the two compartments in the MessageShape to an RGB color code. (Maybe there is a better place to set the color but this does work. Another option would be the “ OnShapeInserted“)

 

public partial class MessageShape

{

 

      public override void OnInitialized()

      {

 

            ...

 

MessageShape.compartmentDescriptions[0].TitleFillColor = Color.FromArgb(132,150,173);

 

MessageShape.compartmentDescriptions[1].TitleFillColor = Color.FromArgb(189,162,123);

      }

 

}

 

As you can see in the image below the color of the compartments are changed (compared to the colors in some previous posts). Also a “TooltipText” is displayed when moving the mouse over the connector shape. The tooltipText is composed out of the information of the two shapes that are connected by the connector.

 

To be continued...

posted on 11/18/2005 10:14:57 PM UTC  #   
 Wednesday, October 19, 2005

Great news! The DSL Team just released a guide that describes how to customize the features and capabilities of the DSL Toolkit (September CTP). Thanks guys!

 

This guide describes for example how to use custom code to create: “transparent text decorators”, straight lines, shadow and gradients, container object, etc. All techniques that can dramatically improve the modelling experience of your DSL.

 

A lot of other interesting features are covered in this document including the explaining code samples. Of course al of this is subject to change in the next releases of the Toolkit. But if you don’t like that, don’t use CTP products and wait for the V1 release!

 

Anyone interested in this guide, go get it following this link to the DSL Toolkit forum.

 

Have fun and expect a lot of the features described in this guide in the DSL we are building.

 

posted on 10/19/2005 4:19:22 PM UTC  #   
 Monday, October 10, 2005

 

It’s been some time since I wrote about the progress of the DSL we are working on. Not because there is no progress anymore but mostly because I am very busy with my regular work so I simply have no time left to write a post. It’s still my intention to have the DSL fully operational by the time V1 of the DSL Toolkit is available and so far I don’t see any reasons why this wouldn’t be possible.

 

I am now using the September CTP of the DSL Toolkit. Unfortunately the migration of the whole project took some more time than expected. I followed all steps of the (perfect) migration guide but still I got an error when trying to use the designer of my Language in the debug instance of Visual Studio.NET. It took me some time and a little help of the DSL Team to find out that my designer definition file contained some “shape definitions” that I wasn’t actually using anymore. These shapes were now part of a compartment shape in my language but I had forgotten to delete the definitions from the file. The May CTP build didn’t have any problems with this. The very cryptic error message (“package …. Has failed to load properly”) wasn’t very helpful for finding the problem. So solving this issue took some time. The good thing of course is to see that more and more validations are built in the Toolkit. I have good faith that the final release will provide more descriptive (helpful) error messages for these new validationsJ.

 

What are we working on now? Currently we are working on the “generating WSDL part”. This WSDL will be based on the service description that is modelled by using the DSL. For me this basically this comes down to writing some T4 templates to mix the “service description” (modelled in the language) with some pure C# code that Christian wrote to generate the WSDL. This work is almost done. From there we can do basically everything we want with code generation.

 

There isn’t much information available about writing T4 templates. Anybody interesting in writing these templates might find some help in this blog post of Gareth Jones (DSL Team) about the T4 syntax. A little information about how to navigate over your DSL model can be found here on the Domain Specific Language Tools forum.

 

Some directives that I needed within the templates:

 

To include files (create some sort of a function library):

<#@ include file="filename.extension" #>

 

To reference an assembly:

<#@ Assembly Name="System.Web.Services.dll" #>

 

To import a namespace:

<#@ import namespace="System.Web.Services.Description" #>

 

A lot more information about writing templates will be made available in the V1 release of the Toolkit. By then all the API that can be used for writing templates will be stable and no longer subject to change.

 

To be continued…

posted on 10/10/2005 6:56:07 PM UTC  #   
 Monday, September 12, 2005

Currently I am working on code generation for the DSL we are building. The DSL Toolkit comes with some sort of a framework that can be used to build templates for generating artifacts (based on the model). In this release of the toolkit however, writing templates is a poor experience (just my opinion J). The templates are displayed as “text files” within the Visual Studio.NET 2005 IDE without any syntax coloring. This makes large templates very hard to read. As you can see in the image (small part of the template) below it is very hard to make a distinction between the C# code that is needed for generation the artifact and the C# snippets that are part of the artifact and thus part of the template. The image below is only a simple and small part of the templates so imagine a large template.

The good news is that the DSL team is working on (or at least thinking of) providing a richer template writing experience. Hopefully this will make it in the next CTP release of the DSL Toolkit! I definitely I can’t wait for a better coding experience!

 

Enough complaining. As you can see in the two images below, it is possible to generate some code based on a model. The template above also shows that navigation the model isn't too hard either (foreach ServiceArtifact in this.Service.ServiceArtifacts). The image shows the C# code that is generated based on the definition of the “service interface” in the DSL designer. No rocket science but it works. Of course, more code can be generated but this is just an example.

One of the artifacts that I will generate (based on the model) will be an xml representation of the modelled concepts and their relations. I think that might become handy if I want to use another code generator engine that isn’t based on the DSL Toolkit Templates and thus might not integrated very well with the DSL model. Hopefully this gives me some more flexibility when it comes to generating the artifacts in the future.

To be continued…

posted on 9/12/2005 8:15:21 PM UTC  #   
 Monday, August 29, 2005

It’s time for another update on the progress of our DSL. Christian and I have been working on the underlying model of our Domain Specific Language we are building. We made some changes to make the model better reflect the “service design” domain.

  

For anyone interested in some background information on this topic (service design), go read this article of Christian. It explains some fundamental concepts that might help you understand the domain model a little better.

 

Please note that the model below is still work in progress. It is very likely that it will change in the near future. Some of the concepts and relations are based on restrictions in the current release of the DSL Toolkit and might not reflect the perfect “designing services” world. Also getting the code generation to work properly might force some changes in the underlying model. For now let’s have a quick look at the model and briefly discuss a few concepts. (I am sure in the end a more detailed explanation of the complete model will follow)

 

If you have seen the previous version of the model you notice the new “DataContract” concept in this version of the model. The “DataContract” describes the data that we need to exchange. In our language the “DataContract” is a reference to an XSD description of the data, therefore the “DataContract” concept has a name, “schemalocation” and a “namespace property”.

 

The “Message” concept (previous “RequestMessage” and “ResponseMessage”) has an embedding relation (solid line in the model) to “DataContract”. The “Message” concept reflects the messages we need to exchange the data that we defined in the “DataContract”. A message can hold one or more “DataContracts”. Messages can be of the type “Inbound” or “Outbound”.

 

The “ServiceOperation” concept in the model reflects the definition of a  serviceoperation of the service. The “ServiceOperation” has a “MessageExchange” property that can be set to either “OneWay” or “RequestResponse”. Based on this property the serviceoperation will have a reference (dotted line in the model) to one or two “Messages”.

 

Another interesting (?) design decision in the model is the embedding relation from the “Service” concept to the “Message” concept. We want to explicitly display the “Message” and “DataContract” concepts on another level than the other “ServiceArtifact” concepts. As you can see in the picture below of the “ServiceDescription Explorer” (part of the designer of this language), there are two child notes below the “Service” (CustomerService) concept. The “Messages” node as the root for the messages and datacontracts and the “ServiceArtifacts” node acting as the root for all other items.

 

Ideally we would have displayed the messages and datacontracts under the appropriate serviceoperation in the “ServiceDescription Explorer”, but to get that to work we needed some changes in the relations between the concepts. In our case this would result in concepts participating in more than one embedding relation which is not allowed in the current release of the DSL Toolkit. This will probably change in the next upcoming CTP build!?

 

On the left of the “ServiceDescription Explorer” you see an example of these three concepts used in the designer based on this early preview of the model. Here we modelled a services operation (GetCustomerDetails) referencing one inbound message (GetCustomerDetailsRequest) and one outbound message (GetCustomerDetailResponse). Both messages hold one or more datacontracts in the message.

 

Hopefully this clears some things up for the “DataContract”, “Message” and “ServiceOperation” concepts. More information on the other concepts in another post. 

 

To be continued…

posted on 8/29/2005 8:42:59 PM UTC  #   
 Wednesday, August 24, 2005

It’s been a while since I wrote about the progress of my DSL experiment. Why does it take so long? Is it so hard to build a DSL? Well, actually sometimes I think it is. It takes some time to really understand what is going on in all the files that are part of the DSL solution. Most of this is because of the technology preview status of the toolkit and therefore the limited documentation that is available. In the current release some of the files have to be maintained by hand which can only be done if you have a good understanding of the xml structure of the files. Most of this manual work will disappear in the next release of the toolkit. Luckily there is an active forum and the DSL Toolkit team that is willing to help!

 

But, let’s continue on the status. Three weeks ago Christian Weyer of Thinktecture contacted me to let me know he liked the work I am doing in my DSL experiment. As you can read in this post on his blog Christian is thinking about using DSL’s for modelling service interfaces and data contracts for some time. We decided to discuss this “service modelling” domain via email and to join forces and build this language together.

 

So, the last few weeks we discussed the artifacts that can be identified within the service domain and how to model them in our DSL. As a result some of the names of the concepts that I modelled in an early version of the language have changed to make them more descriptive and some new concepts are introduced. Currently I am making the last changes in the model. After that we have to finish the designer for the language and finally we can do some code generation. In another post I will show a next version of the model and hopefully explain some of the ideas behind it.

 

Hopes this clears thinks up. The experiment is not dead. Expect to hear of it a lot more in the coming days, weeks, months.

 

To be continued…

 

posted on 8/24/2005 7:57:56 PM UTC  #