




免费预览已结束,剩余64页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Visual Studio DSL 入门 1 什么是特定领域开发和DSL 特定领域开发是用来解决重复发生的问题的方法,针对每次发生的问题,通过进行总结和分析,他们之间相同的方面可以一次性的解决而经常变化的方面,可以采用一种特殊的语言表达针对这个特殊语言,我们可以建立模型或者表达式,然后插入到固定部分 对于我们软件行业的解决方案来说,固定部分一般采用传统的设计和实现方式,可以为框架,平台,解释器或者编程接口提供可扩展性,具有高度的抽象性和可复用性而特定领域语言专门用来创建变化的部分,从而使整个解决方案可具有可应用性 特定领域语言(DSL,Domain Specific Language)是一种特别用来描述某一专业领域内涵的描述语言,其实它并不陌生, HTML ,SQL都算的上是DSL的例子 几种其它DSL MPS /mps/ JetBrains公司的DSL工具,通过这个平台可以直接定义规则,生成代码 MetaEdit+ / 图形化的DSL工具 Oslo /zh-cn/data/ee460940(en-us).aspx 微软新推出的图形化DSL语言,但是Oslo和我们要介绍的DSL Toolkit还是有些区别的,这里有一些介绍/keith_short/archive/2008/11/06/oslo-and-the-dsl-toolkit.aspx .Oslo由 “M语言,工具Quadrant,关系存储组成 GMF,EMF /modeling/gmf/ 使用 Eclipse Modeling Framework (EMF) 和 Graphical Modeling Framework (GMF) 技术来为领域特定语言(DSL)产生领域特定建模(DSM)辅助工具 什么是Visual Studio DSL Vistual Studio DSL 工具,是微软针对特定领域开发而专门设计的.包含在Vistual Studio SDK中(vs 2010中将是单独安装),允许开发人员自行设计专属的图形化工具,它内置了模型的相关支持,以及模型与图形之间的支持,还包括对模型的验证,规则,事务的支持,同时还允许开发人员在结合VS.NET的一些扩展VSX一同使用比如工具条,菜单等可以将模型与T4一同使用,从而生成目标代码Vs.Net现在的类设计器,分布式系统设计器(Distributed System Designer),LinqToSql设计器,EntityFramework设计器都是基于VS.NET DSL开发的,VS 2010新增了UML Modeling Project,终于提供了对类图,时序图,用例图等的支持,这也是基于Vs.NET DSL来实现的为什么要使用DSL工具 上面介绍了几种DSL工具,但是我们为什么要使用它呢?它又能给我们带来什么呢? 很关键的一点,DSL和UML不同,是用来解决问题的,而不是描述问题.如果你正在你的工作和解决方案中重复编写着相同或者相似的代码,而且这些重复的代码能够单独出来采用生成的方式,那么你就可以考虑结合DSL工具来生成这些代码. 可能有人会说,那这和使用现有的这些基于数据库的代码生成工具(Codesmith,李天平的codematic等)又有何不同呢?DSL是站在领域专家的高度,而非软件开发专家来开始解决问题,如果需要对数据库进行设计,然后再生成代码Coding,那么你这个工具只能说是开发人员的一个辅助工具,只是面对实际开发人员,而这在大型的软件系统当中会有些力不从心 采用DSL的开发过程定制 1.找出问题的固定部分,并把这些固定固定部分放在通用架构或平台中通用的部分基本上都是我们根据长期的经验和积累抽象出来固定的比如我们使用的Enterprise Library中已经将数据访问操作,日志操作,验证缓存等封装起来提供调用 2.识别可变性和发现DSL. 找出其中变化的部分,并设计DSL, 通过DSL的表达式或模型提供给问题一个解决方案. 在使用Enterprise Library过程中,你发现其中大部分的变化的部分其实也相对固定,他们还是基于你的模型,基于你的实体模型,服务模型,如果把这些元数据抽象出来,通过DSL来实现这些元数据的配置,那么就可以把这些部分直接生成到你的目标解决方案中 优势 1.大幅度的提高生产率. 生成代码可比人工复制粘贴快多了。 2.使系统的规范性更强. 每个开发人员对某一个功能的都会有不同的实现方式,采用DSL设计模型,结合代码生成能够使功能的实现相对固定. 3.降低了犯错的机会. 4.使非开发人员,那些顾问和售前,也能够直接了解模型。使开发过程提前,甚至顾问的调研需求时,就可以使用工具和客户沟通,抽象需求,从而提供给二次开发人员使用. 5.能够在较高的抽象层次对解决方案进行验证,过早的发现问题. 6.可以基于同一个模型配置不同的技术实现过程.降低技术难度和工作量。比如上次介绍的Sculpture,就可以针对不同的层次,提供不同的技术选择。针对同一个模型,我们可以选择使用Entity Framework或者NHibernate。UI层可以选择A MVC,Sliverlight,WPF等不同的实现方式. 7.DSL不局限于生成我们的技术方案,还可以用来生成构建脚本,文档,计划等。 8.使解决方案进行技术转移变得相对容易,通过修改生成器或解释器就可以做到。模型元数据相对固定,使我们的解决方案相对规范。我们只需要生成不同的代码就可以了。 当然,这也是有前提的,一是开发DSL,进行抽象整合需要成本。二是并不是所有的解决方案都适合使用DSL,比如一个门户网站,可能相对固定的部门很少,可以定制的部分也很少,就不适合使用,如果对不适合使用的强制使用就会陷进定制化陷阱。在设计和开发时,一定要保留一定的灵活性,因为不可能所有的代码都能够生成,你必须提供一定的扩展性,保证能够对生成的代码进行扩展。另外就是一定要保证实现的规范,实现方式太多,会导致你的DSL过于复杂。有些时候你甚至需要舍弃一些实现,舍弃一些需求。“简单的问题的解决应该简单化,复杂问题的解决应该可能化”(smalltalk的创始人AlianKay). 系列介绍 本系列一开始将通过一个案例简单的介绍DSL的开发流程,这个案例来源于DSL Tools Lab,主要介绍DSL的一些简单开发方法,其中也包括T4与DSL结合完成代码生成,DSL工具的部署. 主要是完成一个状态机的DSL应用,具体我们会在接下来一一介绍。 对DSL的开发有过简单的了解后,我们会对完成一个实际使用的完整的开发工具的开发。在这个过程中也会包含介绍DSL设计和开发过程以及应该注意的问题,当然也会包括DSL以及VSX的一些比较深层次的应用。 参考 Visual Studio DSL 工具特定领域开发指南 Doamin-Specific Development With Visual Studio DSL Tools Visual Studio DSL 入门 2 相信如果看过一上篇你已经对 dsl有了一定的了解,接下来我们就来开始我们的这个系列的入门,V Dsl在国内可能使用的人少之又少,不过希望这个系列能够使看到的人能够对dsl有一定的了解,使之能够成为产品方案选型时的一个参考,能够对阅读的人有所帮助. 准备环境 由于 2010并未正式发布,所以这一系列基于vs 2008 sp1进行开发,Dsl tools是包含在VSX当中的,所以需要下载 Vistual Stutio.Net SDK 1.1安装,下载地址为:/zh-cn/vsx/default(en-us).aspx 另外代码生成采用的是T4,为了方便T4的编写,需要下载T4编辑器/,遗憾的是V至今还没有内置T4编辑器,在vs 2010中也不会提供。 需求说明 我们完成的这个简单的Demo类似于UML中的状态图(Statechart Diagram), 这个状态机由状态(states)组成,各状态由转移(transitions)链接在一起。状态是对象执行某项活动或等待某个事件时的条件。转移是两个状态之间的关系,它由某个事件触发,然后执行特定的操作或评估并导致特定的结束状态。 状态(State)的要素: 名称: 将一个状态与其他状态区分开来的文本字符串;状态也可能是匿名的,这表示它没有名称。 分类: 状态分为初始状态(initial state)和结束状态(end state). 进入/退出操作: 在进入和退出状态时所执行的操作。 内部转移: 在不使状态发生变更的情况下进行的转移。 子状态: 状态的嵌套结构,包括不相连的(依次处于活动状态的)或并行的(同时处于活动状态的)子状态。 延迟的事件: 未在该状态中处理但被延迟处理(即列队等待由另一个状态中的对象来处理)的一系列事件。 转移(Transitions)的要素: 源状态: 转移所影响的状态;如果对象处于源状态,当对象收到转移的触发事件并且满足警戒条件(如果有)时,就可能会触发输出转移。 事件触发器: 使转移满足触发条件的事件。当处于源状态的对象收到该事件时(假设已满足其警戒条件),就可能会触发转移。 事件一般都有一个名称,但是有些转移没有事件名称,称为自动或隐式转移. 警戒条件: 一种布尔表达式。在接收到事件触发器而触发转移时,将对该表达式求值;如果该表达式求值结果为 True,则说明转移符合触发条件;如果该表达式求值结果为False,则不触发转移。如果没有其他转移可以由同一事件来触发,该事件就将被丢弃。 操作: 可执行的、不可分割的计算过程,该计算可能直接作用于拥有状态机的对象,也可能间接作用于该对象可见的其他对象。 目标状态(可选): 在完成转移后被激活的状态。 参数: 转移可能有参数,这个参数为事件触发器的事件方法的参数 事先弄清楚这段说明是很重要的,因为我们的模型,我们的元数据都来源于需求问题的描述 计划 一个简单的入门系列计划大致包含几下几步: 1. 创建一个简单的DSL模型 2. 创建我们的元数据模型,包含状态机(StateMachine),状态(State),转移(Transition).可能实际的会对我们需求有些取舍,比如不考虑子状态等. 3. 创建相对我们的元数据模型的图形展现. 4.规范我们的模型和图.添加规则(Rule)和验证(Validation) 5.在Visual Studio实验室环境中测试我们的Dsl项目 6.改善我们的用户界面. 7.针对我们限定的元数据针对一个框架创建代码生成. 8.创建安装程序发布Dsl项目安装包资源 1.DSL Tools Lab /DSLToolsLab 系列教程 2.台湾微软Paul的DSL系列视频教程 /zh-tw/vstudio/cc963628.aspx 3.Domain-Specific Development with Visual Studio DSL Tools 目前知道的唯一一本关于专门关于Vs.NET DSL的书,有对应的中文译本. 4.VSX的一系列深入进阶 /blogs/divedeeper/default.aspx?PageIndex=1 Visual Studio DSL 入门 3-创建一个简单的DSL模型 从这节开始我们就开始我们的DSL之旅, 首先确保你已经安装了Visual Studio Sdk,并且使用的是Visual Studio 2008.我们先大概创建一个简单的DSL项目,通过这个项目来了解dsl的开发环境和流程.1. 打开VS.NET ,新建-项目, 点击其它项目类型-扩展性(Extensibility). 这里列出来了扩展类型的项目,包括Addin,VSPackage,Dsl等项目类型,选择Domain Specific Lan guage Designer”,点击确定 2.接下来进入DSL创建向导,将会提供四种DSL模型模板提供我们选择,其实他们只是给我们提供了不同的Sample提供查看,也方便我们更方便的开始. Class Diagrams 由UML类图组成,包含类,接口,关系,组合,属性,操作等. Component Models 组件模型,子组件组成的组件. Minimal Language 只包含一个简单的空的语言模型 Task Flow 创建类似UML状态图模型 3. 在这里我们选择Minimal Language,并保持Language Name默认即可,点击下一步,设计Language的模型文件的后缀名和文件图标。如果你输入的后缀名已经被使用,中间的框中会列出搜索到的注册的后缀名列表。在这里我们输入sm作为后缀名,保持使用默认的图标. 4. 点击下一步,进入到产品设置,主要设计产品名称,所属公司,项目名称空间.这些信息将会包含在最后生成的项目中,在最后的产品部署中起到作用。在这里我们不进行更改,可以直接保持默认即可. 5. 下一步进入到签名设置,在扩展开发中任何需要部署的Package都需要强命名(将会注册到GAC),可以选择自动创建一个Key,也可以选择使用已有的key. 6. 我们选择直接创建强命名key,点击下一步,这是一个设置总结界面: 我们直接能查看到所有的设置信息,可以通过上一步下一步进行更改,也可直接点击左侧的导航来定位更改,确认无误后,点击完成。向导(Wizard)会自动给我们构建项目.我们暂且不管生成的这些项目结构,切换到解决方案资源管理器,点击上面的最后面的按钮“转换所有模板”(Transalte All Template).完成后,点击Debug运行,就会打开Visual Studio实验室环境(Experimental hive),也就是上面的Minimal Language界面,可以大概操作一下了,相当神奇吧,这就完成了第一个DSL项目的开发.同样你也可以选择其它三种模型,效果在上面已经列出来了. 7. 我们再来看一下生成的项目结构,整个解决方案总共有两以下两个项目组成(其它有三个,另外就是运行后的Testing项目,稍后介绍). Dsl: 根据你的模型数据(DslDefinition.dsl文件)生成的有关模型的操作,包括模型关系,序列化,图形,连接器等 DslPackage: 支撑Dsl能够在V里运行,以及和V交互的操作,包括菜单,工具条,游览器等 Dsl项目设置成了针对DslPackage项目的友元程序集(通过AssemblyInfo的InternalsVisibleTo),DslPackage中可以直接访问Dsl中的内部成员,DslPackage其实也是根据DslDefinition.dsl生成的深入了解这两个项目的结构是非常有必要的,我们会在随后的深入过程中介绍。 8. 查看这两个项目,发现大部分都是由后缀名为tt的文件组成,这就是t4文件(Text Templating Transformation Toolkit),类似于asp,ruby这样的解释性语言,读我们的模型生成cs代码,可以看到每个tt文件都附属了一个cs代码文件.绑定到了每个t4文件可以右键运行自定义工具Run Custom Tool,就会调用TextTemplatingFileGenerator解析t4模板文件生成目标代码,也可以向我们刚才那个点击上面的按钮转换所有的模板文件. 9. 打开Dsl项目中的DslDefinition.dsl文件.(这是通常情况下我们使用的最重要的文件,包括我们的Dsl的所有的模型元素数据,它附属的DslDefinition.dsl.Diagram是它的图形显示文件). 这就是模型设计的主区域,我们来看一下它的组成部分: 1). 工具条,这里包括模型,关系,图形. 这个工具条与.Dsl文件关系。 2). 模型元数据. 这些概念的东西我们在下一切会介绍. 3). 图形展现. 设计模型的展现信息,通过中间的那条线与模型对应起来 4). Dsl Details编辑窗口, 用来编辑Dsl相关的一些信息,比如关系。 5). 解决方案文件夹,注意上面的黄色区域就是”转换所有模板“按钮,点击下面的Dsl Explorer页签,切换到Dsl浏览器. 这里会列出来当前Dsl文件里的模型,模型元素Element,图Shape,类型,连接器Connector,Connection Builders,以通读对模型浏览器,工具条,序列化的设置。我们对Dsl的大部分设计都会在这里完成. Ok,就到这里,下次将介绍一些基础概念. Visual Studio DSL 入门 4- 基本概念 刚接触Visual Studio DSL时,被它的基本理论概念迷惑了很长时间, 我的建议是如果能够很快的理解这些概念最好.如果短时间内理解不了就大概了解下这些基础概念,就没有必要为了每一个概念一直深入,搞得自己头疼,倒不如在以后的实践中慢慢深入,理解并加深这些概念. 开发一个DSL需要创建的几个不同的组成部分:域模型,图形符号,工具箱,资源管理器和属性窗口,验证,序列化和部署,打开上一节我们创建的LanguageSm项目中的DslDefinition.dsl文件,可以看到在中心文档区域有左右两部分(两个泳道). 1.左侧是元数据模型(域模型). 也就是域类和域关系 2.右侧是图形符合,也就是图形元素(Diagram Elements). 其实我们是在用DSL本身在创建DSL,这些描述本身也是在用DSL 另外,域模型与图形符号之间通过连接器(Connectors)连接,域类之间可以通过关系relationships连接. 域模型 (Domain Model) 每一个DSL的核心都是一个域模型,它定义了语言所代表的各种概念,它们的属性,以及它们之间的关系。在模型驱动开发中,我们的模型要抽象出来,并用DSL的语法描述出来,这也就是用域模型来描述,只要我们有了域模型,工具箱,图形展现都是基于域模型然则创建的。 域模型有两个概念: 1.根域类(root Domain Class) 任何一个DSL有且只有一个根域类,它和你的图形对应,这里说的图形是整个图形的概念。从我们上一节的项目中可以看到,我们创建的时候默认就自动创建了根域类(ExampleModel)和它对应的图形(ExampleShape)。 2.域类(Domain Class) 和根域类不一样,ExampleElement是真正意义上的模型。并且它有一个属性,名称为Name,类型为String. 域关系(domain relationships) 1.嵌入关系(embedding relationship) 嵌入关系表示一个模型能够嵌入在另外一个模型中。在我们的dsl中的可以找到嵌入关系ExampleModelHasElements,把ExampleModel和ExampleElement联系起来(见下图). 在ExampleModel这一端的属性名为Elements,这个集合属性是它包含所有的ExampleElement, 重数为0.*,表达它可以包含零个或者多个ExampleElement, 域角色是指它在这个关系中扮演的角色,角色名你可以通过点击域角色(这条线)在右面的属性里面看到,角色名往往和这一端的源属性名相反,和另外一端的属性名一致。 在ExampleElement这一端的属性名为ExampleModel,表示它所从属的ExampleModel类型,重数为1.1 ,表示它可以并且只可以从属于一个ExampleModel. 简单来说,这个嵌入关系也就表示了在我们的上一切最后运行起来的Dsl中,我们的ExampleModel模型中能够放多个ExampleElement,对于每一个ExampleElement只能从属于一个ExampleModel. 2.引用关系(reference relationship) 在我们的Dsl中看到引用关系ExempleElementReferencesTargets把两个ExampleElements关系起来,表示在两个ExampleElement之间可以建立ExempleElementReferencesTarget关系,引用关系一般有图形表示,所以在设计时通过拖动一条线来把两个模型关系起来,和嵌入关系一样,引用关系也可以设置多重性,表示是否允许和多个模型同时建立引用关系。在我们的例子中源和目标相同,重数为0.*,表示一个ExampleElement可以与多个其它的ExempleElement建立引用关系。 注意这里这不是代表着两个ExampleElement之间可以建立多个重复的引用关系,而是指不同的ExampleElement之间。允许重复的关系需要在关系的属性中设置Allows Duplicates为True.另外很重要的一点,Dsl会对每个域关系生成一个单独的类,模型中建立的每个关系都是这个类的一个实例。我们可以通过属性中的Code下面属性进行设置来控制生成的代码,我们可以设置GeneratesDoubleDerived属性为True,每个关系会生成两个类,父类ExampleModelHasElementsBase包含所有的实现,子类ExampleModelHasElements是一个partial类,所以你可以重载父类的方法来实现你自己的逻辑。另外我们也可以通过这种机制来实现生成的代码里实现某个我们自定义的接口。注意,同样也可以在域类上进行设置。 在这里我觉得有必要对几个概念加强区分一下: 域类域模型: 域模型包含域类和域关系,域类代表领域中的不同的类型,域关系代表两个域类中的关系信息。 (1) 域模型 -虚线里所所有的 (2) 域类Library (3) 域类Person (4) 域关系 (5)重数 * (表示在一个域模型中,一个Library可以有多个Person). (6)重数 1 (表示一个Person,只能存在于一个Library中). (7)源角色 (8)目标角色 域属性属性 在一个域模型中,一个域类可以有一堆域属性,这是和领域挂钩的,是对元数据的描述。但是对于每个域类,我们还可以在DSL设计器中的属性编辑器中,也会列出来一些属性,比如描述,名称等。注意这里的名称属性和这个域类所具有的Name属性是不一样的。这里的属性列出来的是域类的属性,也就是这个域类叫什么名字. 而Dsl图中列出来的是它的领域属性,而且每个域属性其实也是一个元素,所以他本身也会有一些属性,这里的Name其实就是它在图中显示出来的名字。 好了,今天就到这里,先消化下. Visual Studio DSL 入门 5-理解生成的域类和域关系 上一节我们大概介绍了一些V Dsl的域模型的一些基本的概念,这一节我们再回到我们生成的LanuageSm项目,看一下生成的域类以及域关系,介绍一下Dsl运行时的Store,然后再来介绍一下需要注意的一些关键点。为我们下一节具体设计我们自己的Dsl做最后的准备. 1. 首先找到Dsl项目中模板DomainClasses.tt生成的DomainClasses.cs,我们来查看一下它由两个类组成: 其实也就对应着我们域模型中的根域类ExampleModel和域类ExampleElement.我们仔细再来看一下ExampleElement类的具体结构.可以发现: 1).字段是Guid类型的,这样更方便关系类中直接引用属性,后续我们也会发现在验证,规则中也会经常使用属性的Guid字段变量来代表属性. 2).我们看到上一节我们看到的关系生成的属性,ExampleElement与ExampleModel的嵌入关系,生成了ExampleModel类型的ExampleModel属性. ExampleElement与自身的引用关系,由于重数是*,生成了强集合类型LinkedElementCollection属性. 3).属性中的Name代表域类的域属性Name。 2. 我们再来看一下域关系,找到DomainRelationships.tt生成的类文件DomainRelationships.cs,查看类图,显示类图中的属性为关系或者是组合关系: 1)可以看到域关系对应的类通过Guid对应的字段关联域类. 2)通过上面的类图,可以看到域关系类对应的属性与域类的关系,它分别存储了关系对应的源Source和目标Target的属性。 3)我们可以找到一些静态方法,比如在ExampleModelHasElements类中: GetElements(ExampleModel) - 获取关系中一个ExampleModel对应的所有的ExampleElement GetExampleModel(ExampleElement) -获取关系中一个ExampleElement对应的ExampleModel 另外还可以通过GetLink,GetLinks, GetLinksToElements,获取指定元素之间的关系。 3.很有必要在这里也对Dsl的运行的机制有一些了解 ,那就必须在这里介绍一下Store. 1)在Dsl运行期间,模型元素都被存储在内存中的Store中,Sotre也提供了一系列的操作:模型元素和关系的创建,操作,删除,Redo/Undo,规则,事件等,相当重要,在Dsl开发中经常会涉及到Store的操作。 2)当一个模型文件被打开时,会自动重建一个Store,并且加载模型文件中的所有的模型和关系的实例,这个过程我们会在后面介绍。 3) 每一个域类都继承ModelElement,每个域关系都继承自ElementLink(ElementLink其实也继承于ModelElement). 在Store中加载的每个模型其实都是ModelEment的一个实例,每个域关系都是ElementLink的一个实例。可以通过Store甚至可以操作它们的属性,监听创建,删除等事件. 4.有一些细节性的应该注意的问题在这里零散的总结一下: 1).区分两个域类是嵌入关系还是引用关系,可以考虑这域类在模型浏览器里的展现,如果嵌入在模型浏览器中(Model Explorer)那就可以采用嵌入关系,否则就是引用关系. 2).关系的重数虽然可以任意选择,但是在有些情况下会有些限制,比如在嵌入式关系中: 嵌入关系目标角色的重数可为One 或者是ZeroOne,因为一个ModelElement只能被嵌入一次. 如果一个ModelElement是多个嵌入关系中的目标角色,那么目标角色的重数必须都为ZeroOne,因为它只能在同一时间在一个关系中扮演目标角色。 在一个完整的域模型中,每个域类(根域类除外)必须是一个嵌入关系的目标,不然就不能够构成一个完整的模型树,也就不能够处理序列化 当然,可能大家会对这些规则有些不知所措,没关系,你可以不理这些规则,按照你的方式去设计,在保存或者是验证(右键Validate All)时,会在下面的错误窗口提示你的。 3)每个域类都应该有Name Domain Property.可以通过从工具栏拖Named Domain Class创建域类,自动带出此域属性,也可以手动添加域属性,然后指定域属性的Is Element Name 为True,此属性的值会在序列化处理时使用. Visual Studio DSL 入门 6-DSL的图形表示1 到现在为止,我们还是只是介绍模型相关的东西,还没有接触到Dsl的模型的展现,对于一个Dsl来说,没有图形展现也是可行的,不过对于一个开发工具来说,要提供一种方式来操作我们的元数据,Visual Studio DSL在图形展现这方面提供了不错的支持,不过对于复杂的Dsl来说,图形的展现往往需求很复杂,现在的图形化支持在一定程度上也未必能够满足一些特定的需求, 有总比没有好,期望微软会在这方面会有所加强。 还是以我们创建的LanguageSm项目为例,我们大概介绍一下界面表示相关的概念,打开DslDefinition.dsl文件,这次我们看泳道(也就是树线)的右边: 一. 图表 我们看最下面的LanguageSmDiagram,这就是图表元素,它是存储形状和连接器映射的容器,代表设计界面自身,映射到模型的根域类(图形元素Diagram Elements都是与模型相对应的),也就是映射到我们例子里的ExampleModel,我们来看一下图表的属性: 在这里,我们可以对图表的外观,代码,文档,公开样式属性,资源几个方面进行属性设置,Dsl会收集设置的这些信息,然后根据T4模板,在Dsl项目的Generate Code文件夹下面生成Diagram类,我们也可以对这个类进行扩展,实现图表方面的一些自定义,比如设置背景图,显示网络等。如果你想实现Dsl模型的自己的界面表示方式,也需要实现自己的图表元素Diagram类. 二.编辑器 编辑器分为两种类型:(图形)设计器和自定义编辑器.编辑器的定义在Dsl资源管理器(Dsl Explorer)中的“编辑器”(editor)节点下,这里的定义的属性用于生成EditorFactory类(熟悉VSX的应该知道,我们会在后面介绍),工具箱等,我们来看一下默认的设计器的属性: 这里需要提示一下,在dsl设计的过程中,有很多时候需要dsl浏览器和属性对应操作使用,可以通过右键属性来进行设置。 属性里设置了编辑器对应的图表元素,编辑器的GUID,根域类,以及存储Dsl模型的文件扩展名,与文件关联的图标。或许你不太明白这些属性代表什么意义,没有关系,以后会明白的。 我们在第一节就说过, Dsl模型并不一定要有图形编辑器的,我们也可以在这里添加我们自定义的编辑器,你可以右键删除默认的Editor,然后在根结点LanguageSm上右键添加自定义编辑器,然后设置上面说的那些属性,然后实现自己的DocView,在这里有详细流程,具体的方法我们也会在后面详细介绍. 三.形状 形状是Dsl图形符号的重点,因为形状和模型元素一一对应(前面说的ExampleShape是一个几何形状,和根域类对应),可以使模型元素形象化,这也是Vs.Net DSL图形化DSL的特点. 形状又分为以下五个不同的类型,这五个形状在工具箱上都有,可以直接拖动到图形区域创建对应的形状,建议现在没有必要太去细化,而只需要记住他们的样式,能够按需所有,具体怎么设置还是到使用的时候再去研究: 1.几何形状(GeometryShape) 左侧为形状的模型,右侧为调试后运行的显示模型,形状中的文本装饰器NameDecorator就是用来控制我们显示图形中的文本,你可以查看装饰器的属性,控制文本的显示,包括文本,显示位置等. 对于几何形状,除了文本装饰器以外,你还可以添加IconDecorator(装饰图形上显示图标),ExpandCollapseDecorator(装饰图形的展开收缩) 2.隔间形状(CompartmentShape) 隔间形状是带有隔间的几何形状,一个隔间形状有可以有多个隔间: 同样,对于隔间形状,你也可以象几何形状那样添加其它的装饰器. 3.图像形状(ImageShape) 图像形状是显示图形非轮廓的形状: 可以看到,图像形状显示的和我们普通的几何形状是不一样的,我们可以针对图象开关设置显示的图像和图标资源,我们来看一下上面的图像形状的属性,在最下面我们定义了显示的图标: 4.端口(PortShape) 端口是依附在形状轮廓上,并只能绕轮廓移动的特殊形状,除此之外,和普通的几何形状没有区别。 5.泳道(Swimlane) 泳道用来将图表分割成行或例,我们看下面的状态流程图: 参考资源 1. Visual Stuido DSL 工具特定领域开发指南 2.Using WPF As The Designer Surface In DSL Tools Gokhan AltinorenVisual Studio DSL 入门 7-DSL的图形表示2 在上一节介绍了 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),当选中时,生成的代码会添加自定义的代码段,你必须实现对应的方法才能够编译通过,在指定的方法里,你可以自已返回父元素和父形状. 隐藏行号 复制代码 ? 1. if(element is global:Company.LanguageSm.ExampleElement)2. 3. / Method:4. / private DslDiagrams:NodeShape CreateShapeForExampleElement(ExampleElement newElement)5. / 6. / 7. / must be implemented in a partial class of LanguageSmDiagram. Given an instance of ExampleElement,8. / 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.9. DslDiagrams:NodeShape newShape = CreateShapeForExampleElement(global:Company.LanguageSm.ExampleElement)element);10. if(newShape != null) newShape.Size = newShape.DefaultSize; / set default shape size11. return newShape;12. 你必须在LanguageSmDiagram的partial类里面实现这个GetShapForExampleElement方法才能够编译通过. 装饰器映射 我们再来看一下Decorator tab,这里主要是映射属性和装饰器,在某些情况下,装饰器的外观可能会需要随着模型信息的更改而动态更改,装饰器映射主要是来定义这一行为。 上面显示的是Dsl中的ExampleShape的Name装饰器的装饰器映射,显示属性(Display Property)主要是针对文本装饰器(text decorator),在这里也就是用来设置需要显示的文本对应的域类的域属性. 可见性筛选器(Visibility Fi
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年甘肃省中共嘉峪关市委党校(市行政学院)招聘公益性岗位人员考前自测高频考点模拟试题及答案详解(易错题)
- 2025辽宁大连金普新区卫生系统招聘事业编制工作人员164人模拟试卷完整参考答案详解
- 死后遗产赠与合同7篇
- 2025湖南省第二人民医院(湖南省脑科医院)高层次人才公开招聘20人考前自测高频考点模拟试题及答案详解一套
- 2025年春季上海华二松江实验教师招聘模拟试卷及答案详解(历年真题)
- 2025年上海市普陀区教育学院附属学校实习教师招聘考前自测高频考点模拟试题含答案详解
- 2025年春季中国邮政储蓄银行广西区分行校园招聘模拟试卷及答案详解(网校专用)
- 2025广东韶关乐昌市九峰镇村基层公共服务站系统操作员招聘2人考前自测高频考点模拟试题及1套参考答案详解
- 2025甘肃省卫生健康委系统招聘51人考前自测高频考点模拟试题及答案详解(有一套)
- 2025安徽六安市中医院紧缺人才招聘模拟试卷及1套参考答案详解
- 2026中国电建集团成都勘测设计研究院有限公司招聘笔试备考试题及答案解析
- 2025广西崇左凭祥市委宣传部招聘编外工作人员1人考试参考题库及答案解析
- 2025江西赣州南康赣商村镇银行招聘4人考试参考题库及答案解析
- 社保协议书模板6篇
- 企业安全生产责任书范本大全
- 工艺设备变更风险评估报告模板
- 红星照耀中国考试真题及答案
- 2025离婚起诉状民事诉状(离婚案件用)
- 前端Vue3项目实战教程
- 智算中心高性能计算系统设计方案
- 中央八项规定精神应知应会测试题有答案【夺分金卷】附答案详解
评论
0/150
提交评论