Modelling with Domain-Specific Languages

Introduction

With the entire industry moving as quickly as it has been for the past few years, it is not surprising that every once in a while you discover a technology or capability that has been around for a number of years yet has escaped your attention.

Domain-Specific Languages (specifically the implementation within Visual Studio) has been one of those cases for me, but over the past few weeks I’ve been spending my spare time playing with the models and considering its role in the production (primarily) of design documentation. I’m always on the look-out for ways to improve communication with members of the customer’s team and one thing is obviously true – it doesn’t matter whether they are managers, business users, or analysts – pretty pictures do a great job of communicating complex ideas simply.

I can almost hear you saying now ‘but Domain-Specific languages have been around for years (since VS2005 in fact) … so how is it that this is new to you!’ Well I was feeling pretty embarrassed about that, until I presented the concept internally to some of my colleagues at work and found that no-one else had investigated DSL either. Now I don’t feel so bad.

So for those readers who haven’t used DSL in the past, it’s probably safe to say that you’ve at least used the models produced using the toolkit. The DSL modelling SDK is responsible for many of the graphical designers within Visual Studio, such as;

  • The Visual Studio Architecture Tools
  • The Entity Framework designer
  • The BizTalk ESB Toolkit Itinerary designer
  • The Web Services Software Factory designer

Why I’m Excited

Generating a nice diagram is well and good – but the fact is Visio can do that. The power of the DSL SDK comes with the extensibility – some of the features that have me interested are;

  • Customized Rules and Validation. This is key to help new team members understand the model
  • Model Generated meta-data generation. A lot of data we deal with is meta-data that ultimately needs to be loaded into a database, or system of some form.
  • Model Generated design documentation. I’m quite excited about the idea of transforming (using the Visual Studio’s T4 templates) the model xml into Word XML or similar.
  • Distributable. As most models can be executed within Visual Studio Shell, they could easily be shared with business analysts and customer representatives who might not already have Visual Studio.

On top of this, model development is fast! Without writing any code at all it doesn’t take long to produce a model. Models could easily be built for short-lived project requirements.

Getting Started

As with any technology that has been around for seven years already, there is some good material on the internet for getting started, and I’m not trying to replicate that in this post.

A Basic Example

As an example, consider for a moment the process of defining document libraries in a SharePoint environment. This often involves defining a Content Type for the library, configuring the document library (possibly with additional library-specific columns), and possibly adding an approval workflow.

The Domain Class model below outlines three core types (note I’ve hidden some of the relationships from simplicity here);

  • Content Types, including;
    • Embedded relationship to Columns
  • Document Libraries, including;
    • Embedded relationship to Columns
    • Reference relationship to Content Type
    • Reference relationship to Workflow
  • Workflows, including;
    • Several Domain Properties defining attributes for workflow configuration

Each of these Domain Classes have been mapped to Component Shape and Connector elements to support the visualization of the model.

The resulting model allows users to graphically model the Content Types, Document Libraries and Workflows required for the solution, resulting in the following diagram. In this case I’ve shown Content Types in purple, Document Libraries in orange and Workflows in lime green. As you can see, this provides a high-impact top level view of the domain model, and is well suited to including in design documentation communicating the solution to customers, developers and maintenance teams alike.

While the design process is being conducted, it is often simpler to capture any additional details required for the solution being developed at the same time – this is where diagrams in Visio start to fall short a little. Since the DSL model is hosted within Visual Studio, we have full access to the property grid – so all custom Domain Properties can be captured simply.

To extend this example a little further, consider the possibilities of artifacts that could be generated from this model such as;

  • Automation of web service calls to implement the content types / libraries and workflows directly from the model
  • Generation of Word tables containing the properties stored against each Domain Class. This could include the detailed attributes from the property grid that are not shown in the visualization.
Advertisements

Successfully upgraded TFS 2010 from Beta 2 to RC on EC2

Once again I have my TFS instance on EC2 up to date, and I’m able to connect to it successfully from my Visual Studio 2010 RC instance here at home. One word of advice though; once you install VS2010 RC, VS seems to crash if you then try to install Team Explorer 2010 Beta 2 so make sure your code is all checked in before the upgrade, otherwise won’t be able to make this available to anyone else on your team until the process is complete!

I was surprised that I didn’t run into a few issues as part of this process, but the upgrade was fairly painless – thanks mostly to the TFS 2010 Beta 2 to RC Upgrade Guide posted by Brian Krieger. I ran into a bit of trouble setting up SSRS and WSS again … but that was my own fault, not an issue with the upgrade process (I’d forgotten the credentials I’d used last time … L).

The good news though is that now seems to be working, including my old VS2010 Beta 2 solution files which opened without any issues or the need for an upgrade. 

I did come across a breaking change in the TFS APIs. It would seem that the TeamFoundationServer class no longer supports the AuthorisedIdentity property (in fact the TeamFoundationServer class has now been depreciated in favor of TeamProjectCollection). Changing the reference to use TeamProjectCollection.AuthorizedIdentity seems to have resolved the problem, and everything is building again.

TFS 2010 Beta 2 – Custom Work Item Controls. Step 2, Work Item Setup

Overview

[Edit: Source code for the control discussed in this post can be found here: TFS TimeSheets (Codeplex).]

In the first post (Step 1, Getting Started) in this series I looked at how to create a basic Work Item Custom Control for Team Foundation Server 2010, and went through the process of configuring and installing the custom control for use on the Task work item.

Today I’m looking at setting up the Task Work item definition to allow create a new field for our custom work item control to persist time sheet data to.

The screen shot below depicts my goals for the control; however this post focuses more on how to create and configure the control than the actual time sheeting ability itself. Yes, I know this one isn’t going to win any prizes for prettiness … but that can be fixed later 🙂

As we are restricted within Team Foundation Server to a non-relational structure for our work item data, my current thinking is that time sheet data will be stored as XML within a new field configured on the work item. The other option I considered was looking at the ‘History’ field type … but a bit of investigation suggests that the way the work item history control works is to look at the various revisions of the work item, rather than store a collection of values.

Prerequisites:

Before getting started, the following prerequisite setup should be completed:

  • Visual Studio 2010 Beta 2 (for development)
  • Visual Studio 2010 Team Explorer Beta 2 (for testing)
  • Team Foundation Server 2010 Beta 2
  • The output from the project setup in Step 1.
  • A new reference added to our custom control library to Microsoft.TeamFoundation.Client
  • A new reference added to our custom control library to Microsoft.TeamFoundation.WorkItemTracking

Modify the Work Item Template

Using the following command the existing work item template for the Task work item can be extracted from the Team Foundation Server.

C:\>”C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\witadmin.exe” exportwitd /collection:localhost\defaultcollection /p:”{ExistingProject}” /n:Task /f:Task.xml

If you haven’t worked with the work item template in the past, at this stage it’s worth having a good read through the documentation. For the purposes of the changes today we are only going to need to add a new field; however there is a lot of value in understanding some of the other features available within the schema.

The first thing we need to do is declare a new field to store the time sheet data. The XML fragment below shows the new field definition is black bold font. It should be noted that the refname is unique across the entire Team Foundation Server collection database, so be sure to apply a suitable name at this stage. I tend to prefix all my custom fields with ‘Custom’ just to make them easier to identify.


<FIELD name=Authorized As refname=System.AuthorizedAs type=String syncnamechanges=true />
<FIELD name=”TimesheetRawData” refname=”Custom.Timesheets.TimesheetRawData” type=”PlainText” />
</FIELDS>

We also need to add the FieldName attribute to the control definition for the WorkItemTimeSheetControl:

<Tab Label=TimeSheets>
<Control Type=WorkItemTimeSheetControl LabelPosition=Top FieldName=”Custom.Timesheets.TimesheetRawData” />
</Tab>

The modified work item can then be imported back into TFS 2010 using the following command:

C:\TFS>”C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\witadmin.exe” importwitd /collection:localhost\defaultcollection /p:”{ExistingProjectName}” /f:Task.xml

Using the IWorkItemControl Members

The Work Item Custom Control we created earlier implemented the IWorkItemControl interface. Using this interface we can get access to the currently loaded work item, and manipulate its values programmatically.

The full documentation for the interface can of course be found on MSDN, but below are my additional notes on the usage of some of the members.

WorkItemDataSource A reference to the work item is provided to the user control via the WorkItemDataSource property. The property itself is defined as an object, but so far I’ve found that this reference can be safely typecast to a stronger type of Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem.
WorkItemFieldName If the work item control has been setup with a fieldname value then this will be provided to the custom control via the WorkItemFieldName field.
InvalidateDataSource The InvalidateDataSource method is called during the loading (and unloading) of a work item. This method should be used to populate the fields of the Work Item Custom Control with their persisted values, or default values for a new work item.

Writing to the Work Item using the Object Model

A small number of standard properties may be set via strongly typed properties on the Work Item … however the majority of the Work Item data must be accessed from within the Fields collection.

CurrentWorkItem.Fields[WorkItemFieldName].Value = TimeSheet.Serialize(TimeSheet);

Whenever any data is changed within the Fields collection the work item interface automatically detects that the work item is ‘dirty’ and sets it to appear modified in the user interface with the * next to the work item name.

The one gotcha I did come across on the way was how to obtain the name of the current user in the context of the connection to Team Foundation Server. It turns out this can be retrieved from the following property:

CurrentWorkItem.Store.TeamFoundationServer.AuthorizedIdentity.DisplayName;

The changes I’ve made to the control at this point have been very basic. I’ve added a couple of user input controls to the form, and setup the add button handler to add a new time sheet entry entity to a time sheet list, then serialize the resulting list back to the work item based on the WorkItemFieldName.

At a high level, the functionality implemented is:

  • Ability to enter a new timesheet entry
  • Ability to view all timesheet entries associated to the work item
  • The value of Remaining Work is decreased automatically based on the minutes entered
  • The value of the Completed Work is increased automatically based on the minutes entered

Testing the Changes …

As before, it is necessary to reopen the testing instance of Visual Studio 2010 – otherwise the old work item definition may still be cached.

If we reopen Visual Studio then create a new Task work item our custom control should be displayed under the TimeSheets tab, and loading / saving Task work items should result in our changes being persisted to the database.

References

While working through this investigation process I’ve found the following resources very useful, and my thanks go to their authors:

Can’t debug VS2010 from VS008

So as part of my experiments with creating and installing Work Item Custom Controls for use in Team Explorer 2010 I inevitably wanted to be able to attach a debugger to an instance of Team Explorer 2010 to interrogate the Work Item object model at runtime.

I’ve done this before for Team Explorer 2008 and wasn’t anticipating any problems. The basic setup can be obtained using these instructions on the Team System Notes blog.

Having followed these instructions I hit a bit of a roadblock. It turns out that VS2008 doesn’t like attaching a debugger to a VS2010 instance. If VS2010 is setup as the start-up application then an error is thrown when starting the project: “The debugger’s protocol is incompatible with the debuggee“. I’m guessing here, but I’d assume that the issue is that VS2010 has been compiled using .NET 4.0, and as VS2008 only supports up to .NET 3.5 the debugger is unable to correctly attach to a 4.0 managed process. I had hoped to keep this machine (the primary one I use for work) free of the full VS2010 components … however having hit this issue I’ve had to download and install the beta 2.

Anyway, the upshot is that installing VS2010 and attaching the debugger to another VS instance from there solved the problem.

TFS 2010 Beta 2 – Custom Work Item Controls. Step 1, Getting Started

Overview

A few months ago I spent a week or so getting my head around the Custom Work Item Controls in Team Foundation Server 2008. At the time it was obvious that a lot of value could be added to our development teams if we could add some additional custom work item functionality to our processes.

My original intent at the time was to build a work item explorer that could navigate through work items based on their relationships … but that is fairly redundant now that we have proper work item hierarchies in TFS 2010. This time my intention is to have a look at how we can improve the way we record our time against tasks within Team Foundation Server.

This post (Step 1, Getting Started) will cover the process of setting up the required project and setup files, creating a basic ‘Hello World’ custom work item control and loading that control into the work item interface.

Prerequisites:

  • Visual Studio 2008 or 2010 (for development)
  • Visual Studio 2010 Team Explorer Beta 2 (for testing)
  • Team Foundation Server 2010 Beta 2

Visual Studio Project Setup

Creating Custom Work Items Controls is much like creating any other control library in Visual Studio. The control itself is based on the standard UserControl base class, and should be setup within a .NET Class Library Project.

Before going any further, we’re going to need to add a reference to the TFS Work Item Tracking Controls assembly. This is installed as part of Visual Studio 2010, and can be found in the following folder:

C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll

At a minimum, we’ll also need the following artefacts in our solution:

  • One User Control (WorkItemTimeSheetControl)
  • One Work Item Custom Control definition file (.wicc). Note that it is important to set the Build Action for this file to ‘Content’ on from the properties window.

Create the User Control

There is nothing overly special about a user control housed within a Work Item form – except that it implements the IWorkItemControl interface. For the moment the goal is only to create a user control and embed it within the Work Item form, so the control itself contains nothing more than the compulsory ‘Hello World’ label in bold 24pt black font.

We’ll setup the various members of the IWorkItemControl interface in more detail in a future post – for the moment a basic implementation with the default NotImplementedExceptions removed will do the job. Just create basic backing variables for any of the properties that need to be defined.

Create the Work Item Custom Control definition (WICC)

The .wicc file is an XML file that defines the custom control to be loaded within a work item. When a Custom Control is referenced within a Work Item Template, Visual Studio will look within the custom controls folder for a .wicc definition file that matches the name of the required custom control. In the case of current custom control, Visual Studio will be looking for a file named WorkItemTimeSheetControl.wicc.

The following XML is the contents of the WorkItemTimeSheetControl.wicc file:

<?xml
version=1.0
encoding=utf-8 ?>

<CustomControl
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema>

<Assembly>TimeSheetControl.dll</Assembly>

<FullClassName>TimeSheetControl.WorkItemTimeSheetControl</FullClassName>

</CustomControl>

Create the Windows Installer

Unfortunately the runtime for a Work Item Custom Control is not defined on the Team Foundation Server instance, but rather must be installed on every Visual Studio client machine that will be interacting with the work item.

The one gotcha for the setup folder is that all the output must be installed on within the custom controls folder on the client machine. On Vista, this is located at C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\10.0 … though this will vary depending on the OS.

  1. Create a new Setup Project within the solution
  2. Add a new ‘Custom Folder’ named CommonAppDataFolder to the output of the setup project.
  3. In the properties window for the new custom folder, set the Default Location to [CommonAppDataFolder].
  4. Create the folder structure shown in the screenshot above under the CommonAppDataFolder. (Microsoft, Team Foundation, Work Item Tracking, Custom Controls, 10.0)
  5. Add the Primary Output and Content Files from the user control class library we created earlier.
  6. Build and install the setup file on the local machine.

The client components are now all in place – the only remaining step is to add our custom control to one of the work item templates.

Modify the Work Item Template

I’m going to select the Task work item from the MSF for Agile Software Development 5.0 Beta 2 process templates as the testing work item template to apply our new custom control to.

Using the following command the existing work item template for the Task work item can be extracted from the Team Foundation Server.

C:\>”C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\witadmin” exportwitd /collection:localhost\defaultcollection /p:”{ExistingProject}” /n:Task /f:Task.xml

A couple of notes here:

  1. The WITAdmin tool is new to TFS 2010. When working with TFS 2008 the witimport / witexport tools would be used instead.
  2. In TFS 2008 adding custom controls to a work item template broke the process editor power tool – so all operations to import / export the work items must be done by command line. I am not sure whether this is going to be supported in the TFS 2010 power toys or not.

Now that we’ve got the work item template extracted we need to modify it to include our custom work item control. I’ve chosen to add the control to a new tab at on the bottom half of the screen.

The XML fragment below shows the addition of the time sheet control to the Task work item file in bold black font. Make sure that the ‘Type’ attribute for the Control node is set to the name of the .wicc file that has been deployed to the client machines.

        …

    <Tab
Label=Attachments>

    <Control
Type=AttachmentsControl
LabelPosition=Top />

        </Tab>

            <Tab Label=”TimeSheets”>

                <Control Type=”WorkItemTimeSheetControl” LabelPosition=”Top” />

            </Tab>

        </TabGroup>

</Layout>

</FORM>

</WORKITEMTYPE>

</witd:WITD>

The modified work item can then be imported back into TFS 2010 using the following command:

C:\TFS>”C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\witadmin” importwitd /collection:localhost\defaultcollection /p:”{ExistingProjectName}” /f:Task.xml

Testing the Changes …

Back on the Visual Studio client machine, load up an instance of Visual Studio 2010 Team Explorer Beta 2 and open a Task from within the team project that has had the modified work item template loaded. Assuming everything has gone to plan a new tab should exist on the Work Item form, and the custom control should have loaded and displayed correctly.

One gotcha to keep in mind here – Team Explorer will cache the work item templates and controls – so it may be necessary to restart the Team Explorer client in order to see the updated layout.

Next Steps

Hopefully this ‘getting started’ post is of some use to others as they work through this process … or at least will help me out next time I get some time free to continue with this side project J

Now that we’ve got a user control successfully loading from within the work item layout, my next (likely) steps include:

  • Adding interaction with the Work Item data model
  • Investigating how / if the TFS Web Interface can have a similar custom control applied
  • Investigating whether using WPF controls will simplify the implementation of think client / web client work item templates
  • Putting together some actual logic to solve the initial issue of time sheeting!