OK, slightly embarrasing this one, but I decided to add it here for a couple of reasons.
- One, lets face it, only pretend people are reading this (comment to prove me wrong)
- Two, it :( stumped me for a week, and if I can help just 1 (pretend) person avoid the horrid "No standard web pages containing all your search terms were found" Google page, then my karma will lighten a touch
What I wanted to do, I though would be relatively common for a DSL, but I was
struggling to work out how to do it. I needed Model Element (lets call it an
Entity for the moment) on my DSL Diagram to have 1 : * properties. I didn't want
to have to model all of them as separate Model Elements related to the Entity on
the DSL Diagram, but embedded in the Entity itself, with an Add New .. Context
Menu option, such as adding class attributes on the Class Diagram in Visual
Studio
|
|
I created a 'Property' Domain Class, and assigned it to the Entity Domain Class
as an embedded relationship, Transformed Templates, fired up the Hive and hoped
that it would 'Just Work'. I didn't hold much hope, and it turned out I had no
right to as all I got for my (lazy) troubles was a nice rectangle representing my Entity when I dragged
one onto my diagram.
|
|
As it turned out, it was quite simple, perhaps sematically unintuitive. In fact it was simple enough to allow me to make a complete mess of a few days coding.
What I did was note that there was a Compartment Shape available to use in your
model, and assumed it represented, not the whole shape for the Entity, but the
indivdual Compartment for my attributes, so I added it to my Domain Class as
well as its basic shape, and tried mapping my properties to it.
|
Now, things began to get a little more confusing, my transformation ran fine,
however, when I fired up the Hive, I was met with the following in the generated
code:
// Multiple mappings have been defined for the class Entity.
// Either implement a method as described below, or remove the multiple
mappings from the DSL definition.
//
// Method:
// private DslDiagrams::NodeShape CreateShapeForEntity(Entity newElement)
//
{
//
}
// must be implemented in a partial class of Blog1Diagram. Given an instance of Entity,
// the method should return a new shape or connector instance that should be
associated with this element. If no shape or connector should be created, the
method should return null.
DslDiagrams::NodeShape newShape =
CreateShapeForEntity((global::Pelion.Blog1.Entity)element);
At this point, in my defense, I was beginning to suspect that I was missing
something fairly important (and most likely obvious), and did attempt to RTFM
(in an MSDN sense, something fairly basic and confusing at this early stage of
DSL Tools), and to WTFV (watch the training videos), none of which touched on
this element of modelling. The sample code in the VS SDK did seem to point to
the fact that I was on the correct track, but I didn't pay to much attention to
them at first.
Instead I tried to code a new shape, something I am sure would have worked, by
my results were laughable. I won't go through them here.
Anyhow, to cut a painful story short, I fired up the SDK samples again, and had
that 'I've lost how many days?' sinking feeling when I realised the answer was,
of course, obvious. The CompartmentShape defines the Domain Class's shape and
all its compartments, and what the confusing message in the code was telling me
was that I had defined 2 shapes, and which one did I want.
I deleted the non-Compartment shape, added a compartment and associated the
Entity Property to it.
I hope this has helped at least one pretend reader on their way.
|