Using DSL Integration Service (DIS) – Part 2

June 8, 2007

In the last post I’ve introduced the DSL Integration Service and it’s own usage scenarios. Now I will get into the code, illustrating the implementation of one specific scenario:

Suppose you already have a DSL which enables the specification of business entities. Now Suppose that you need to implement a DSL for the user interface specification. It would be nice to have the possibility to reference the entities defined using the entities DSL, when specifying the user interface with the second DSL.

To do so I’ve implemented a new Visual Studio 2005 tool window that displays all the business entities and corresponding attributes in all available models. Then selecting one user interface model I’m be able to create my user interface specification by doing drag & drop of the available business entities into the UI model.

These are the steps you need to follow to implement something similar:

First you need to mark the entities DSL as exportable. You do so by editing the Package.tt in DslPackage project:

[Microsoft.VisualStudio.Modeling.Integration.RegisterAsExportable(

typeof(<#= directiveName #>DomainModel),

typeof(<#= directiveName #>SerializationBehaviorMonikerResolver),

typeof(<#=domainModelRoot#>),

typeof(<#= directiveName #>SerializationBehavior))]

internal sealed partial class <#= dslName #>Package : <#= dslName #>PackageBase

{

}And for the target DSL that’s all. You need only to garantee that , in the DSL definition, you do not have any element with the attribute “Generates Double Derived” with a “True” value assigned because if you don’t the integration service will generate an error. This limitation as already been assumed in the DSL forum.

To implement a Visual Studio 2005 tool window you need to create a new Visual Studio Integration Package

In the VSIP you need to get the reference to the Integration Service. With the service reference you can get an instance of the business entities domain model browser. With the domain model browser you can get a reference to all exported instances of a given model element. Finally you expose the elements data by geting a reference to each exported instance:

IDslIntegrationService service = Business_Entities_Selector.GetGlobalService(typeof(IDslIntegrationService)) as IDslIntegrationService;

IDomainModelBrowser domainModelBrowser = service.GetDomainModelBrowser(“Company.Models.Entities”);

ReadOnlyCollection<ExportedInstance> exportedInstances = domainModelBrowser.FindAllInstances(domainModelBrowser.GetExportedClassByNamespace(“Company.Models.Entities\BusinessEntity”));

BusinessEntity resolvedElement = (BusinessEntity)service.ResolveExportedInstanceInDocument(“Company.Models.Entities”, “mell://” + exportedInstance.Namespace, true);

Still in the VSIP project you need to enable the Drag & Drop operation. You do so by calling the DoDragDrop method in the ItemDrag event from the TreeView control:

private void TreeView1_ItemDrag(object sender, ItemDragEventArgs e)

{

DoDragDrop(e.Item, DragDropEffects.Copy);

}

In the User Interface DSL you need to first enable the drag & drop operations in corresponding model:

protected override void OnAssociated(DiagramAssociationEventArgs e)

{

base.OnAssociated(e);

// Ensure we have a view

if (e.DiagramView == null || e.DiagramView.DiagramClientView == null)

return;

// Wireup the drag/drop support

Control ctrl = e.DiagramView.DiagramClientView;

ctrl.AllowDrop = true;

ctrl.DragOver += new DragEventHandler(OnDragOver);

ctrl.DragDrop += new DragEventHandler(OnDragDrop);

}

Then implement the OnDragOver event:

private void OnDragOver(object sender, DragEventArgs e)

{

e.Effect = DragDropEffects.Copy;

}

And finally the OnDragDrop event. The model element creation it’s done here:

private void OnDragDrop(object sender, DragEventArgs e)

{

if (e.Data.GetDataPresent(typeof(TreeNode)))

{

using (Transaction transaction = this.Store.TransactionManager.BeginTransaction())

{

ExampleElement exampleElement = (ExampleElement)this.Store.ElementFactory.CreateElement(ExampleElement.DomainClassId);

TreeNode entityNode = (TreeNode)e.Data.GetData(typeof(TreeNode));

exampleElement.Name = entityNode.Text;

foreach (TreeNode node in entityNode.Nodes)

{

Attribute attribute = (Attribute)this.Store.ElementFactory.CreateElement(Attribute.DomainClassId);

attribute.Name = node.Text;

exampleElement.attributes.Add(attribute);

}

ExampleModel exampleModel = GetModel(this.Store);

exampleModel.Elements.Add(exampleElement);

transaction.Commit();

}

}

}

You need to implement all this in a partial class of the UserInterfaceDiagram class

And that’s it. You now can start building you user interface specification by using the entities definitions made in another DSL.


Implementing a VS2005 Macro for automating transformation and exporting of outputs from DSL templates

May 6, 2007

For those who are working with Domain Specific Languages Designers, there is on recurring two step task that should be automated: Tranforming and exporting the various templates ouputs to the proper locations in our working project.

To do so we can implement a simple macro that does the job for us.

Basically we need to create a method that call one command that transform all the templates in the current project:

DTE.ExecuteCommand(“TextTransformation.TransformAllTemplates”)

and then call a set of commands to copy the templates ouput to the desired directory. Here is a sample of what I said:

DTE.ExecuteCommand(“Tools.Shell”, “cmd /c copy /Y “”" + GetOriginPath() + “BusinessEntities.cs” + “”"  “”" + BusinessEntitiesDestinationFile + “”"”)

where GetOriginPath()  is defined as:

Private Function GetOriginPath() As String
      Dim lastIndex As Integer = InStrRev(DTE.Solution.FullName, “\”)
      Return Left(DTE.Solution.FullName, lastIndex) & “GeneratedCode\”
End Function

To learn how to assign a macro to a toolbar button check out this site.

To learn how to Edit and Programmatically Create Macros check out this site.


Reseting Visual Studio 2005 Experimental Hive

April 20, 2007

Upon installation of the Visual Studio SDK, a clone of the existing Visual Studio registry is created for use as the default experimental hive.

When developing applications and/or integrations for Visual Studio 2005 with the Visual Studio 2005 SDK, for example using the DSL Tools, the testing and debugging is done using a Visual Studio Instance that are running with a special registry hive, instead of the normal so you don’t mess up your normal Visual Studio operations.

So when you latelly add new add-ons to VS 2005 like the ones for Team Foundation Server they are not automatically registered under the experimental hive. To make sure that experimental hive uses all the recent settings of VS 2005 we need to do a reset to this special instance.

Reseting the experimental hive is done from the VS 2005 SDK.

Here is the command line:”C:\Program Files\Visual Studio 2005 SDK\2007.02\VisualStudioIntegration\Tools\Bin\VsRegEx.exe” GetOrig 8.0 Exp


VS 2005 and Crystal Reports headakes

March 16, 2007

This week I was involved in a project where we needed to implement a small reporting mechanism. As we are using Visual Studio 2005 and Crystal Reports was handy, since it was tightly integrated, we decided to implement some reports with it. Everything went prety fine until the moment of setting the report logon info at runtime. The headakes started.

From my experience i have come to the following conclusions:

  1. If you create a database connection with Integrated Security, no matter what you do, you will never able to switch, at runtime, to SQL Security.
  2. You cannot change the initial server and database name, as well as the user id and password.

Since I could not find any suitable workaround for this problems, I have decided to install the Crystal Reports XI full product and implement a new report from scratch.

Happily everything works fine now, or at least I hope so.

This behavior is absolutly unaceptable in a develoment tool such as the MS Visual Studio 2005. I let this tips for you guys hopping that you don’t spare your precious time.


Installing Enterprise Library, GAT/GAX, CAB and factories under Windows Vista

February 14, 2007

Tom Hollander has posted some usefull tips for installing GAT/GAX and factories under Windows Vista. The same applies to Enterprise Library and CAB

Basically you need to run everything as Administrator.

Another important aspect is that, if you accept the default installation paths of Enterprise Library and CAB, you need also to run Visual Studio 2005 as Administrator when building this solutions. This is because Windows Vista restricts the access to ”Program Files” folder.

For more related information see also this post from Hugo Ribeiro.