在上一节介绍了vs.net dsl的图形符号,其中包括图表,编辑器,形状.在这一节,我们来看一下图形符号与元数据之间的关系,他们是怎么映射在一起的.
模型元素由形状来表示,而域关系则用连接器(Connectors)来表示.图形映射定义了模型元素通过形状可视化表示出来,而连接器映射定义了链接如何通过连接器可视化表示出来.
形状映射
我们先来看一下形状映射,接着打开我们的LanguageSm项目中的Dsl文件. 选中域类ExampleElement与图形ExampleShape之间的线,可看下面的Dsl details:
这个窗口有两个tab,General tab主要是定义域类和图形间的连接, 可以选择形状,域类,设置他们之间的映射关系,Parent element path(父元素路径)指出了引用的域类的逻辑父元素,以及当前形状应当以哪个图表元素作为父亲.
为什么需要指定父元素路径呢?因为设计器在运行时,所有的图表元素(除了图表本身),都必须有父图表元素(可以是图表或形状),这样这个图表才能够知道自己放在哪里,所以我们在这里需要指定形状被创建后哪个图表元素将作为它的父亲.
父元素路径使用简单的路径语法来表示整个元素和链接结构,在我们这个例子中,它指出了从ExampleElement出发顺着ExampleModelHasElements.ExampleModel/!ExampleModel这条中径得到的元素对对应的图表元素,就是形状的父元素所在的图表,在这个例子里,也就是图表本身ExampleModel元素,因为我们的ExampleShape是直接放在图形上的。
另外两个可设置的项,具有自定义的父形状(Has custome Parent Shape),具有自定义的父元素(Has custom parent element),当选中时,生成的代码会添加自定义的代码段,你必须实现对应的方法才能够编译通过,在指定的方法里,你可以自已返回父元素和父形状.
-
if(element is global::Company.LanguageSm.ExampleElement)
-
{
-
// Method:
-
// private DslDiagrams::NodeShape CreateShapeForExampleElement(ExampleElement newElement)
-
// {
-
// }
-
// must be implemented in a partial class of LanguageSmDiagram. Given an instance of ExampleElement,
-
// 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 = CreateShapeForExampleElement((global::Company.LanguageSm.ExampleElement)element);
-
if(newShape != null) newShape.Size = newShape.DefaultSize; // set default shape size
-
return newShape;
-
}
你必须在LanguageSmDiagram的partial类里面实现这个GetShapForExampleElement方法才能够编译通过.
装饰器映射
我们再来看一下Decorator tab,这里主要是映射属性和装饰器,在某些情况下,装饰器的外观可能会需要随着模型信息的更改而动态更改,装饰器映射主要是来定义这一行为。
上面显示的是Dsl中的ExampleShape的Name装饰器的装饰器映射,显示属性(Display Property)主要是针对文本装饰器(text decorator),在这里也就是用来设置需要显示的文本对应的域类的域属性. 可见性筛选器(Visibility Filter)主要是用来设置装饰器根据域类的域属性来决定是否显示,通过Filter property设置依据的属性,在右面的Visibility entries里设置值为多少时,装饰器才会显示,如果依据更复杂的逻辑,我们可以添加计算属性。另外,可见性设置同样可以针对图标装饰器(Icon decorator)进行设置,比如我们可以实现设置当某一实体为继承实体时,就在右上角显示一个小图标。
以上是对所有的形状共有的映射定义,不过对于一些形状还是会有些特殊的地方,我们大概介绍一下:
1.隔间形状.
除了形状映射外,还需要映射隔间:
这个是我们在前面根据Class Diagrams模板创建的项目中的ClassShape的映射,在这里我们可以看到属性隔间(AttributesCompartment)和操作隔间(OperationsCompartment)的映射, 左边是设置用于创建隔间项的元素集合,在这里也是通过属性路径从Class出发找到Attribute,当然这里也可以设置使用自定义的元素集合,和上面一样,你需要自定义实现对应的方法,右边是每个元素需要显示的实际信息,在这里也就是设置对于Attribute元素需要显示的属性Name.
2.端口
端口映射需要注意的是父元素路径确定的元素必须映射到一个可以接受端口的图形上,包括几何形状.隔间形状.另外一个端口形状(或者将自定义父元素设为true),否则将会报错。
3.泳道
当把元素映射到一个应包含在泳道里的形状时,父路径必须标识出映射到泳道的元素。映射泳道时,必须在父路径中标识图表对应的元素,否则会报错,泳道不能以几何形状作为父亲.
连接器映射
形状映射将形状映射到域类,而连接器映射将连接器映射到一个域关系,而且在这里不需要设置父元素路径。 连接器连接了对应的链接的源元素和目标元素对应的形状,同样,在这里可以设置 具有自定义源(Has custom source),具有自定义目标(Has custom target).同样的,可以对连接器映射设置装饰器映射,因为域关系也是有属性的.
好了,到现在为止,我们根据创建的默认的LanguageSm项目,已经大概介绍了Vs.net Dsl的一些基本知识,这些知识是我们在使用vs.net dsl之前必须要掌握的,接下来我们就开始实际创建我们自己的Dsl, 这个项目的需求已经在第二节中介绍过了。
参考资源
1. Visual Stuido DSL 工具特定领域开发指南
2. DSL Tools Lab http://code.msdn.microsoft.com/DSLToolsLab 系列教程
作者:孤独侠客(似水流年)
出处:http://lonely7345.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。