Visual Studio Development Bookmark and Share   
 index > Visual Studio Guidance Automation Toolkit > Linking DSL Files
 

Linking DSL Files

Hi All,

I will try to be as brief as possible.
I've been making a DSL project for 2 months now. And somehow my application need to access the inner-structure of Visual Studio. I went to DSL forum to solve my problem, but someone pointed me to this forum. I hope there is someone here who can help me out.

I dont know if my first question is related to GAT. When I run my DSL project I can add an item in Experimental Window by left-clicking the Debugging in solution explorer and then a window with templates appears. There I can choose my DSL template for the file I want to add. My question is, how can I perform this by only clicking a button I made by myself? How can I show the Add New Item Template window by clicking my button?

And the second one, how can I link DSL files in my project? Let's say I add two new DSL files; test1.mydsl and test2.mydsl. How can I link these two files? For instance, in test1.mydsl I make the relation between System1, System2, and System3. And in test2.mydsl the full diagram of System1 is specified.

Any help will be appreciated. Thanks!

Herru

Herru Perdana  Thursday, January 04, 2007 12:22 PM
Hi Herru,

regarding your 1st question: what you want is to offer a menu item, like when the user right click on item in the solution explorer (i.e. the solution item, a project, a project item, etc) that when selected automatically displays the Add New dialog with your DSL item template preselected?

regarding your 2nd question: currently there is no support in DSL Tools to specify relationships between model elements living in separate model files. However, you may want to take a look at this article "Guidance Automation Toolkit and Domain-Specific Language Tools for Visual Studio 2005: Integration Scenarios" (http://msdn2.microsoft.com/en-us/library/aa905334.aspx) which may help you. The DLL used in that article to support cross language references (that also support single language references) should be be made available by Microsoft as a Visual Studio power toy soon.

Lastly, if you're going to do any GAX/GAT + DSL integration work I would suggest you to take a look at the Clarius Software Factories Toolkit (http://softwarefactoriestoolkit.net) which makes life a lot easier when integrating both technologies.

HTH,
-Victor.
vga  Thursday, January 04, 2007 1:18 PM
Double-clicking on a shape and launch a GAX recipe is something that would require more coding and integration with VS. If you can live with right-click and having your own menu option appear along the other options that appear when you right click, and have a GAX recipe launch when the user selects this option, this is what you need to do:

1) You need to find out the GUID and ID for the designer surface of the DSL you've generated. The ID is fixed to 65536 but the GUID is automatically generated, so you need to take a look at your generated code to find out this one.

2) You need to define a GAX recipe like this:

<Recipe Name="YourRecipeName" Bound="false">
<Caption>Recipe on designer surface</Caption>
<Description>Recipe launched from DSL designer surface</Description>
<HostData>
<CommandBar Guid="Your DSL designer GUID goes here" ID ="65536"/>
</HostData>
</Recipe>

3) Add to the above recipe definition <Action> elements to perform whatever is you need to perform (i.e. show a proceed dialog and then call the built-in Add New dialog).

4) In order to bind the above recipe you need to use a GAX unbound reference, for this you could take different options:

a) write a reference that always return 'true', this will make your menu option visible at all times (when right clicking the designer surface, any shape, etc).
b) write a more elaborated reference that examines the received Target argument (that all unbound references receive) and only return 'true' if you're dealing with the specific type of shape you're intereted in. I think this 2nd option is the one that better fits what you're looking for.

5) Finally, you need to actually bound the recipe with the custom unbound reference written at step 4). For this you usually use the "binding" recipe, which is a recipe that runs every time a package is enabled. In your <GuidancePackage> element you will need to specify which is the binding recipe:

<GuidancePackage xmlns="http://schemas.microsoft.com/pag/gax-core"
Name="DslIntegrationPackage"
Caption="DSL Integration Package"
Description="Shows how to integrate GAX and DSL"
Guid="7c35715b-cc2e-49e5-a50e-90c9c58cce45"
BindingRecipe="BindingRecipe"
SchemaVersion="1.0">

And then you will need to have a recipe named "BindingRecipe" (that is the name I used above, you could actually use any other name here):

<Recipe Name="BindingRecipe">
<Types>
<TypeAlias Name="RefCreator" Type="Microsoft.Practices.RecipeFramework.Library.Actions.CreateUnboundReferenceAction, Microsoft.Practices.RecipeFramework.Library"/>
</Types>
<Caption>Binding Recipe</Caption>
<Actions>
<Action Name="RecipeOnDesignerSurfaceRef" Type="RefCreator" AssetName="YourRecipeName"
ReferenceType="Clarius.GuidanceAutomation.Library.Dsl.DiagramReference, Clarius.GuidanceAutomation.Library" />


And that's pretty much all. It may look like a lot of stuff but it's pretty much just declaratively stuff, besides the custom unbound reference and any specific actions you wouldn't need to write any other code.

In the Clarius SFT, there are ready-to-use unbound references for attaching your recipes to the designer-surface, the model explorer window, a specific shape, a comment shape, links, etc. And there is also a sample called "DslIntegrationPackage" that showcases a couple of interesting integration scenarios.

Hope this helps!

-Victor.
vga  Friday, January 05, 2007 4:02 AM

Hi Marco,

I think what you're looking for is the DesignerSelectedElement value provider (included in SFT). This value provider will load up the currently selected model file into a GAX argument that you can then check its properties, etc from an Action, is this what you want?

Let me know if this helps,

-Victor.

btw, the next public CTP of SFT will include a much enhanced support for binding recipes to DSL and dealing with selected elements.

vga  Wednesday, May 09, 2007 5:12 AM
Hi Herru,

regarding your 1st question: what you want is to offer a menu item, like when the user right click on item in the solution explorer (i.e. the solution item, a project, a project item, etc) that when selected automatically displays the Add New dialog with your DSL item template preselected?

regarding your 2nd question: currently there is no support in DSL Tools to specify relationships between model elements living in separate model files. However, you may want to take a look at this article "Guidance Automation Toolkit and Domain-Specific Language Tools for Visual Studio 2005: Integration Scenarios" (http://msdn2.microsoft.com/en-us/library/aa905334.aspx) which may help you. The DLL used in that article to support cross language references (that also support single language references) should be be made available by Microsoft as a Visual Studio power toy soon.

Lastly, if you're going to do any GAX/GAT + DSL integration work I would suggest you to take a look at the Clarius Software Factories Toolkit (http://softwarefactoriestoolkit.net) which makes life a lot easier when integrating both technologies.

HTH,
-Victor.
vga  Thursday, January 04, 2007 1:18 PM

Hi Victor,

About my first question, you are right. I'm sorry, I made a mistake. I typed "left-clicking" instead of "right-clicking". What you said there is exactly what I want. My scenario is I have this shape of an element that I can double click on it (in my DSL that means I want to make hirearchy diagram from that element), then a "proceed" dialog window appears, and when I click "Proceed" button then theAdd New Itemwindow should appear with my DSL item template preselected. Do you have some idea? :-)

About my second one, I already looked at the article. And once again you are right. Probably I really should check the Clarius toolkit. I found it pretty complicated to integrate GAT and DSL. But thanks for your response. Looking forward for my first one, I would really appreciate it!

Herru

Herru Perdana  Thursday, January 04, 2007 1:46 PM
Double-clicking on a shape and launch a GAX recipe is something that would require more coding and integration with VS. If you can live with right-click and having your own menu option appear along the other options that appear when you right click, and have a GAX recipe launch when the user selects this option, this is what you need to do:

1) You need to find out the GUID and ID for the designer surface of the DSL you've generated. The ID is fixed to 65536 but the GUID is automatically generated, so you need to take a look at your generated code to find out this one.

2) You need to define a GAX recipe like this:

<Recipe Name="YourRecipeName" Bound="false">
<Caption>Recipe on designer surface</Caption>
<Description>Recipe launched from DSL designer surface</Description>
<HostData>
<CommandBar Guid="Your DSL designer GUID goes here" ID ="65536"/>
</HostData>
</Recipe>

3) Add to the above recipe definition <Action> elements to perform whatever is you need to perform (i.e. show a proceed dialog and then call the built-in Add New dialog).

4) In order to bind the above recipe you need to use a GAX unbound reference, for this you could take different options:

a) write a reference that always return 'true', this will make your menu option visible at all times (when right clicking the designer surface, any shape, etc).
b) write a more elaborated reference that examines the received Target argument (that all unbound references receive) and only return 'true' if you're dealing with the specific type of shape you're intereted in. I think this 2nd option is the one that better fits what you're looking for.

5) Finally, you need to actually bound the recipe with the custom unbound reference written at step 4). For this you usually use the "binding" recipe, which is a recipe that runs every time a package is enabled. In your <GuidancePackage> element you will need to specify which is the binding recipe:

<GuidancePackage xmlns="http://schemas.microsoft.com/pag/gax-core"
Name="DslIntegrationPackage"
Caption="DSL Integration Package"
Description="Shows how to integrate GAX and DSL"
Guid="7c35715b-cc2e-49e5-a50e-90c9c58cce45"
BindingRecipe="BindingRecipe"
SchemaVersion="1.0">

And then you will need to have a recipe named "BindingRecipe" (that is the name I used above, you could actually use any other name here):

<Recipe Name="BindingRecipe">
<Types>
<TypeAlias Name="RefCreator" Type="Microsoft.Practices.RecipeFramework.Library.Actions.CreateUnboundReferenceAction, Microsoft.Practices.RecipeFramework.Library"/>
</Types>
<Caption>Binding Recipe</Caption>
<Actions>
<Action Name="RecipeOnDesignerSurfaceRef" Type="RefCreator" AssetName="YourRecipeName"
ReferenceType="Clarius.GuidanceAutomation.Library.Dsl.DiagramReference, Clarius.GuidanceAutomation.Library" />


And that's pretty much all. It may look like a lot of stuff but it's pretty much just declaratively stuff, besides the custom unbound reference and any specific actions you wouldn't need to write any other code.

In the Clarius SFT, there are ready-to-use unbound references for attaching your recipes to the designer-surface, the model explorer window, a specific shape, a comment shape, links, etc. And there is also a sample called "DslIntegrationPackage" that showcases a couple of interesting integration scenarios.

Hope this helps!

-Victor.
vga  Friday, January 05, 2007 4:02 AM

First of all, Wow.....

Thanks, Victor!

Well actually I can use the right-click menu option. And even your point 4b is the best solution, that I thought first (long time ago) it would be impossible with DSL tools. That is why I moved to double-clicking a shape, which is possible. Your answer just hitmy point.

But one thing that I would like you to know, in your point 3, the thing is I dont know how to call the built-in Add New Item window. If you or anyone else have any idea about this, please let me know. Anyway, in the meantime I will try to implement your solution. And I will inform you my progression, or let say if I'm stucked :-).

Herru

Herru Perdana  Friday, January 05, 2007 7:45 AM

A bit information...

...that I thought first (long time ago) it would be impossible with DSL tools...

Whoopss, I was wrong. It is possible with DSL tools. What I meant is double-clicking the shape is easier with just add some lines, rather than right-clicking then you have to go through several steps (CtcComponents etc). Sorry.

Herru

Herru Perdana  Friday, January 05, 2007 8:26 AM

Hi,

i'm working on a Software Factory to describe business processes and i'm using DSL Tools and GAX. i've got a problem which i think fits best here.

i defined a DSL A and want to provide a guidance for defining a DSL B which is supposed to bea subdiagram (a viewpoint)of a shape of DSL A. i have no problems binding a recipe to the shape which actually works quite fine using the Clarius..SingleNodeShapeReference.

what i'm looking for is how to obtain information ofthe shape the reference provides. i need this because i want to create a DIS reference (or just get the name)on the selected shape (in model DSL A)to reference the newly created DSL B.

i've got no idea how this can be done by GAX and i could not find examples in the Clarius SFT or VSIPFactory. i checked outthe GenerateClasses recipe of the DslIntegrationPackage which selects a modeland generates classes for all elements. what i want to do is just do it for one element (the selected one) in the modelfile

maybe i am missing the point of guidances but maybe you have an idea and give some hints.

marco

desa00  Tuesday, May 08, 2007 6:21 PM

Hi Marco,

I think what you're looking for is the DesignerSelectedElement value provider (included in SFT). This value provider will load up the currently selected model file into a GAX argument that you can then check its properties, etc from an Action, is this what you want?

Let me know if this helps,

-Victor.

btw, the next public CTP of SFT will include a much enhanced support for binding recipes to DSL and dealing with selected elements.

vga  Wednesday, May 09, 2007 5:12 AM
Hi Marco,

I've been playing around with DIS quite sometimes now. And I now can reference and point to the property of the shape of an element or the property of the element itself - from other DSL of course. But I did not use any GAT/GAX approach in my integration scenario. If what you want is including GAT/GAX, I think Victor's suggestion suites for you. But if you just want to do that with DIS, then probably I can help you. Let us know.


Regards,
Herru Perdana  Wednesday, May 09, 2007 6:57 AM

Hi,

thanks for the hint with the DesignerSelectedElement. i've not found it yet but i'll not give up :-) and i hope this will solve some of my problems.

Herru, i'm using GAT/GAX because it helps in some way but i'm not bound to it. it's just one approach i thought will help to do what i want to do. i'm always looking for different approaches and i'm very interested in yours. what you wrote about the referencing shapes and elements sounds very interesting to me, so please let me/us know more.

One thing i'd like to provide is for example a menu-item to "implement the subsystem" of a shape/element or if already implemented just go there, like "go to subsystem". whilst the first might be done using a recipe for collecting the necessary data the second is not really a recipe but more a usability improvement.

Regards,

Marco

desa00  Wednesday, May 09, 2007 7:59 AM

Marco,

What you want to do there with the menu item is exactly what I have done. Anyway, actually to talk deep about DSL Tools stuff here is not quite right, because we have special forum that talks about it. But I think fellows here don't really mind if I just put a little bit details about DSL Tools . If you want to know more, you can go to the forum: http://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=61&SiteID=1, there you can find lots of threads and people who arewilling to help you.

Right, let's start. As I've told you before, that I did not use any of GAT/GAX approach, I will give you my own approach using DSL Tools capability with DIS powertoy.

I would go first to tell you my scenario in integrating my two DSLs, so you won't get any confusion later on. I have DSL A and DSL B. Both DSLs are definition of process. With DSL A defines one level higher than DSL B. For example, I have three processes in A; P1, P2, and P3, and I have P1_1 in B as the sub-process of P1, etc etc.

To have the menu-item to implement your integration is quite complicated stuff to do - not difficult, but complicated. Until now I cannot do the Integration automatically. I still have to reference from A to B with the same way like in the sample shipped with DIS.

My approach is, you have to do three steps in general; 1. You provide your designer with the additional command, 2. You instantiate the different DSL's model or open if it already exist, and 3. You do the integration manually, and implement what you like there.

For the 1st step, go to this link: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=350632&SiteID=1, I believe it wont be more than half hour of work.

The 2nd one, I went deep into VSSDK Interop assemblies. I simply performed make file, add file to the project, and open file. In the menu-item, I checked whether P1 already had a sub-process or not (I think this one is easy). If not, I make the file, add it to the project, and optionally open it (depends on what you need and what you want). Here is the code snippet to give you some examples:

Code Snippet

//Put this in a method you like, just mind about where you can get the service..

//Add some important references and using in your solution and file

//Prepare for the out parameters for the GetCurrentSelection method..

IVsHierarchy hier;
uint currentItemId;
IntPtr _hierPtr = IntPtr.Zero;
IntPtr _selPtr = IntPtr.Zero;
IVsMultiItemSelect pMult;
string currentDocument = "";

//Just for the result container (H_RESULT)
int hr;
//Get the service of the file that currently appear in the monitor,carefullon this one
IVsMonitorSelection monSel = this.store.GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
//Get the information of the current file
hr = monSel.GetCurrentSelection(out _hierPtr, out currentItemId, out pMult, out _selPtr);
//Get the project hierarchy
hier = Marshal.GetObjectForIUnknown(_hierPtr) as IVsHierarchy;
//Get the file name and the project path
hr = hier.GetCanonicalName(currentItemId, out currentDocument);
string projectPath = Path.GetDirectoryName(currentDocument);
//Set the new file name, assume you provide fileName for the newfile somewhere
string fileNameToAdd = projectPath + "\\" + fileName+".mydslB";

//Prepare for addition

int retVal = 0;

//Create the file
File.Create(fileNameToAdd).Close();

//Find thecurrent project
IVsProject3 proj = Marshal.GetObjectForIUnknown(_hierPtr) as IVsProject3;
if (null != proj)
{

//Prepare the parameters for the AddItem method
VSADDRESULT[] pResult = new VSADDRESULT[1];
string[] fnarr = new string[1] { fileNameToAdd };
uint cFilesToOpen = 1;

//Add the file...
retVal = proj.AddItem(VSConstants.VSITEMID_ROOT,
VSADDITEMOPERATION.VSADDITEMOP_OPENFILE,
fileNameToAdd, cFilesToOpen, fnarr, hierPtr, pResult);

//If the add successfull, open it... This is optional

if (retVal == VSConstants.S_OK)
{

//Prepare for the parameters of OpenItem

Guid guid = Guid.Empty;

int retVal2;
IVsWindowFrame frame = null;

uint newFileId;
hier.ParseCanonicalName(fileNameToAdd, out newFileId);

/// Perform the OpenItem method TWICE..!!
/// One...
retVal2 = proj.OpenItem(projectFileId, ref guid,
IntPtr.Zero, out aduuh);
ErrorHandler.ThrowOnFailure(retVal2);
/// And once again...
retVal2 = proj.OpenItem(projectFileId, ref guid,
IntPtr.Zero, out aduuh);
ErrorHandler.ThrowOnFailure(retVal2);

/// Release the IntPtr in the memory
if (hierPtr != IntPtr.Zero)
Marshal.Release(hierPtr);
}
}
else throw new NullReferenceException("Cannot reference into null object!");

In this state, I have my DSL B instance added to my current project (the project I run it from my DSL A).

The last steps, 3.

a.Youcan now set the integration manually from A to B just like the sample in DIS. I assume you succeed in this before. I wont go further on this one.

b. Then you can implement the integration. Here is my example, I tried to get the Status property (string)ofSubProcessDiagramP1_1, from P1. If the Status of P1_1 is "High" then the P1 has to be "High" as well. To fire this, I added one more extra menu item.

Code Snippet

//Assume:

// - currentObject is the selected object frommenu itemmethod

// - reference to DSL B's DSL is added in the solution

// - using DSL B's DSL in the file

//Get the shape representation of P1

ProcessShape P1Shape = currentObject as ProcessShape;
if (P1Shape == null) return;

//Get theelement
ProcessP1 = P1Shape.ModelElement as Process;
if (P1 == null) return;

//Check if the references target exists
if (P1.Target.Equals(null)) return;

//Because doing changing appereance, I need to use the transaction

using (Transaction t = this.CurrentDocData.Store.TransactionManager.BeginTransaction())
{

//Prepare the integration service
IDslIntegrationService service = null;
try
{

//Get the service from P1
service = P1.Store.GetService(typeof(IDslIntegrationService)) as IDslIntegrationService;
if (service != null)
{

//Save the reference target somewhere, P1 has property Target for it..
stringsubProcessRef = P1.Target;

//Find the model element that is referenced, mind the namespace..
ModelElement refElement = service.ResolveExportedInstanceInDocument("MyCompany.SubProcess", subProcessRef, true);

//Cool, we can get the element now..Remember, I referenced to DSL B.

//SubProcessDiagram is an element in DSL B
SubProcessDiagram P1_1 = refElement as SubProcessDiagram;

//Set the same status

P1.Status = P1_1.Status;

}

}

//Catchblock of course...

//And commit the transaction, so the visualization of P1 will change

t.Commit();

}

Well, we are pretty much done here. I hope you can understand my approaches. I believe there are a lot easier and simpler way to do what you want. But at least from here I can give you some feeling and hints that hopefully help you with your problem. One more thing, I have to say that I cannot guarantee all these codes work for you. If you have some more questions, please go to DSL Tools Forum.

Good luck!

Regards,

Herru Perdana  Wednesday, May 09, 2007 10:42 AM

Hi Herru,

thank you for this detailed explaination of your approach. it sounds interesting and i'll give it a closer look.

you helped a lot,you helped a lot.

best regards,

marco

desa00  Friday, May 11, 2007 1:46 PM

You can use google to search for other answers

Custom Search

More Threads

• Thrown exception does not trigger Undo in an action
• Bullet points for building a guidance automation package from scratch.
• How to invoke GAT Recipes from XAML conetxt menu
• FolderAdd
• The registry hive containing the path information for the EntLib assemblies can not be found. The repository classes can be crea
• How to remove Extra Lines using TextTemplateAction
• Guidance Automation Toolkit Removal error 2869
• GAT is VS Solution Centric
• Problems with GAT and VS 2008
• Guidance Package Manager fails to appear in visual studio 2008