Friday, February 03, 2006

It’s been a long time since my last post. I have been busy lately working on a few pretty cool things. Unfortunately cannot talk about most of the things yet. But, there’s one thing I can talk about and that is the “ever lasting story” of our Domain Specific Language for designing service contracts.

 

We still plan to make it available for download as soon as the RTM of the DSL Tools is available. In the meantime we are adding some nice features that hopefully improve the usability of the Domain Specific Language. Of course, we have to make some (hopefully not to many) changes to make our custom code work against the changes API of the RTM of the DSL Tools.

 

For now, let me show you some images of some of the features and/or improvements we have been working on. Just to show you this language isn’t dead yet!

 

First of all, as you can see in the image below, we included some nice images in the ToolBox. Not that difficult but I like the Toolbox a little better now.

Further we added some custom menus. One of them to fire the “WSDL generation” another one to fire the “generating model out of WSDL file” option.

 

Below you can see an example of two custom menus that are available when right clicking a MessageShape in our model. When pressing the “Select Message XSD location” (description will probably change!) you get a FileDialog box to select an XSD file that describes the Message. After you selected the XSD, the “schemalocation” property of the MessageShape in the model gets populated with the reference to the XSD.

 

A next thing you can do is right click the MessageShape again and this time you can select the “Select Message from XSD” option. As you can see in the image below, this action results in a new window that pops up and that is populated with all the message definitions in the XSD that you selected in the previous action. You can also click on the messages to see the DataContracts that are referenced in the message.

After selecting a message the MessageShape in the model gets populated with the name of the selected message and the DataContracts belonging to the message are also added to the MessageShape. Maybe no rocket science, but it hopefully makes the Language a little easier to use.

To be continued...

posted on 2/3/2006 2:43:09 PM UTC  #   
 Sunday, December 11, 2005

The new November DSL Tools CTP comes with a totally new Validation Framework. This framework can be used to write constraints for domain classes in your domain model. After trying it out I must admit that the framework makes writing constraints very easy! All validation errors popup in the “Error List” windows in VS.NET, all of this is very cool!

  

However, I was a bit confused. I assumed that whenever a constraint was violated on a domain class in my model this was reflected in the “IsValid” property of the ModelElement and the “Store” that represents my model. None of this is true! While the Error List window shows some constraints violations the “IsValid” of the “Store” (and the ModelElement) returns “true”.

 

Because I need this information in a piece of custom code in the DSL I had to look a little further. I noticed that it is possible execute the validation myself from within the custom code. Have a look at the following code snippet where I am using the “ValidationControler” class to execute the validations. (don’t forget: using Microsoft.VisualStudio.Modeling.Validation;)

ValidationController controller = new ValidationController();

bool isValid = controller.Validate(this.Store,ValidationCategory.Save);

This code lives in the “ServiceDescriptionDiagram” class in the DSL. From there I have a reference to the “Store” that I can use in the “Validate” method. The methode has some other overloads that makes it, for example, possible to validate an ModelElement. The good thing is that this piece of code actually returns the right value (based on the violated constraints in my model). In the code above the value of “isValid” is false whenever a constraint is violated.

 

I am not sure (yet) why the IsValid property on the “Store”, “ModelElement” and “ShapeElement” doesn’t reflect the current state of any violated validation. It might have something to do with the “ValidationCategory” that is part of the validation process. This category can be specified on a constraint to tell the validation framework when a constraint should be validated. Current options are “Menu”, “Save”, “Open” and “Custom”.  It looks like no information about a model or class being valid is stored in the underlying datastore of the model. I assume there is a very “valid” reason for this!

 

For continuing our DSL, this isn’t a problem at all. We can use the “ValidationController” at any place in our DSL to decide if the model is valid enough to start generating artifacts.

 

To be continued...

posted on 12/11/2005 8:07:33 PM UTC  #   
 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  #