第1章 特定领域的开发 1
1.1 简介 1
1.2 特定领域开发 1
1.3 举例 3
1.3.1 软件定义电路 7
1.3.2 嵌入式系统 7
1.3.3 设备界面 7
1.3.4 软件开发过程定制 8
1.4 优点 8
1.5 语言 9
1.6 文本DSL 11
1.7 图形DSL 15
1.7.1 表示结构的规范 16
1.7.2 表示行为的规范 17
1.8 图形DSL的相关内容 18
1.8.1 符号 18
1.8.2 域模型 18
1.8.3 生成 19
1.8.4 序列化 19
1.8.5 工具集成 20
1.8.6 综合应用 20
1.9 VisualStudio中的DSL 20
1.10 定制化陷阱 24
1.11 UML 26
1.12 小结 30
第2章 创建和使用DSL 31
2.1 简介 31
2.2 过程:DSL的递增开发 31
2.2.1 通用化应用程序:定位变化部分*发现DSL 31
2.2.2 自顶向下和自底向上 35
2.2.3 开发DSL:从草图到域模型 36
2.2.4 域模型和表示是分离的 37
2.2.5 改善DSL 38
2.2.6 由DSL驱动框架 38
2.2.7 使用DSL 40
2.2.8 DSL的发展 42
2.2.9 解析式框架 42
2.3 在VisualStudio中创建DSL 42
2.3.1 在VisualStudio中创建一个DSLauthoring解决方案 43
2.3.2 尝试使用DSL解决方案 46
2.3.3 定义DSL 48
2.3.4 生成设计器代码 49
2.3.5 向DSL中添加内容 50
2.3.6 约束 52
2.3.7 定制DSL资源管理器窗口 53
2.3.8 定制属性窗口 54
2.3.9 设计器自定义代码 56
2.3.10 DSL文件的序列化格式 56
2.3.11 由DSL驱动的应用程序 57
2.3.12 部署 58
2.4 第二个DSL例子:工程定义DSL 59
2.5 DSL工具的架构 60
2.5.1 生成的代码 60
2.5.2 DSL工具的架构分层 60
2.5.3 框架程序集 61
2.5.4 DSL项目的内容 62
2.5.5 DslPackage项目的内容 64
2.6 小结 65
第3章 域模型定义 66
3.1 简介 66
3.2 域模型设计器 66
3.3 驻留内存中的Store 68
3.4 域类 69
3.5 域关系 74
3.5.1 嵌入关系 76
3.5.2 重数 78
3.5.3 引用关系 79
3.5.4 关系的派生 80
3.6 生成不包含任何形状的设计器 82
3.7 生成的代码 82
3.8 更多关于域类的讨论 87
3.9 更多关于域属性的讨论 89
3.9.1 自动计算的属性 91
3.9.2 DomainPropertyInfo 91
3.10 更多关于域关系和角色的讨论 92
3.10.1 访问链接 93
3.10.2 更多关于关系派生的讨论 95
3.10.3 DomainRelationshipInfo和DomainRoleInfo 97
3.11 更多关于Store的话题 97
3.11.1 查找元素 97
3.11.2 分区(Partitions) 98
3.11.3 规则 98
3.11.4 DomainModelInfo 98
3.12 小结 99
第4章 界面表示 100
4.1 简介 100
4.2 图形符号概述 100
4.3 图和编辑器 103
4.3.1 图表 103
4.3.2 编辑器 105
4.3.3 设计器 106
4.3.4 自定义编辑器 106
4.4 形状 110
4.4.1 形状分类 110
4.4.2 形状映射 116
4.5 连接器 122
4.5.1 连接器解析和外观 123
4.5.2 连接器和继承 124
4.5.3 连接器映射 124
4.5.4 高级连接器映射 125
4.6 装饰器 125
4.6.1 装饰器的类型 125
4.6.2 定位 127
4.6.3 装饰器映射 127
4.7 在代码中自定义图形符号 129
4.7.1 多行文本装饰器 129
4.7.2 图像形状变量 130
4.7.3 设置背景图片 132
4.7.4 设置自定义连接点 133
4.7.5 更改连接器的路线样式 135
4.8 浏览器 136
4.8.1 默认外观 136
4.8.2 更改窗口图标和标签 138
4.8.3 自定义的节点外观 139
4.8.4 隐藏节点 142
4.8.5 通过代码自定义浏览器 143
4.9 属性窗口 143
4.9.1 默认的属性窗口外观 143
4.9.2 类别、名称和说明 144
4.9.3 隐藏属性和使属性只读 145
4.9.4 属性的传递 145
4.9.5 通过代码自定义属性窗口 146
4.10 小结 147
第5章 创建、删除和更新行为 148
5.1 简介 148
5.2 元素的创建 148
5.2.1 工具箱 148
5.2.2 元素合并指令 150
5.2.3 自定义元素合并指令 157
5.2.4 Re-Parenting与元素合并指令 160
5.2.5 自定义元素工具原型 160
5.3 连接构造器 164
5.3.1 多个源角色和目标角色的指令 165
5.3.2 多链接的连接指令 166
5.3.3 自定义连接构造器 169
5.4 元素的删除 174
5.4.1 默认的删除传播规则 174
5.4.2 控制删除传播 175
5.4.3 自定义删除传播 176
5.5 小结 178
第6章 序列化 180
6.1 简介 180
6.2 保存和加载模型和图表 180
6.3 模型的XML文件格式 181
6.4 元素和属性 183
6.5 关系 184
6.6 交叉引用 186
6.6.1 使用Guid作为引用 187
6.6.2 使用qualifiiedname作为引用 188
6.6.3 对链接引用 189
6.7 图表的XML文件格式 191
6.8 版本控制和迁移 194
6.9 XML模式文件 195
6.10 自定义序列化 196
6.10.1 修改XML元素名称 197
6.10.2 ElementData 199
6.10.3 实现你自己的序列化器 201
6.11 生成的序列化代码 201
6.11.1 自定义的序列化代码 207
6.11.2 自定义对模式文件的影响 208
6.12 小结 209
第7章 约束与验证 210
7.1 简介 210
7.2 选择硬约束还是软约束 211
7.3 DSL工具中的软约束 213
7.3.1 验证方法 214
7.3.2 启用验证 216
7.3.3 触发验证 219
7.3.4 定制验证类别 220
7.3.5 验证行为的继承 223
7.3.6 验证输出 223
7.3.7 在VisualStudioIDE之外使用验证 224
7.3.8 针对外部数据的验证 224
7.4 DSL工具中的硬约束 225
7.5 规则 226
7.6 硬、软约束相结合 229
7.7 小结 236
第8章 生成工件 237
8.1 简介 237
8.2 工件生成方式 238
8.2.1 扩展样式表转换语言(XSLT) 238
8.2.2 使用特定领域API 241
8.2.3 一种基于模板的方法 245
8.3 复杂关系和同步 246
8.4 模板化过程 248
8.4.1 第一个模板 250
8.4.2 与生成代码相关的模型数据 260
8.4.3 开始创建模板库 262
8.5 文本模板的语法 263
8.5.1 指令 263
8.5.2 自定义指令 265
8.5.3 控制块的类型 267
8.6 实际应用中的大规模工件生成问题 269
8.7 高级自定义功能 270
8.7.1 文本模板的架构 270
8.7.2 自定义宿主 272
8.7.3 自定义指令处理器 274
8.7.4 自定义业务流程 276
8.8 小结 282
第9章 部署DSL 283
9.1 简介 283
9.2 安装一个设计器所需要的文件 283
9.3 创建一个安装项目 285
9.4 安装项目内容 288
9.5 自定义安装程序 288
9.5.1 自定义InstallerDefinition.dslsetup 288
9.5.2 自定义settings.ini 289
9.5.3 自定义Strings.wxl 289
9.5.4 自定义Product.ico 289
9.6 dslsetup文件的格式 290
9.6.1 <dsIPackage> 291
9.6.2 <licenseAgreement> 292
9.6.3 <supportingFiles> 292
9.6.4 <vsltemTemplates> 293
9.6.5 <dsISchemas> 293
9.6.6 <vsProjectTemplates> 293
9.6.7 <mergeModules> 294
9.6.8 <textTemplates> 294
9.7 更新安装文件 295
9.8 包加载键 296
9.9 为生成代码部署文本模板 298
9.9.1 在Debugging项目中创建项目模板 298
9.9.2 使用文本模板包含文件 299
9.9.3 在VS项模板中包含文本模板 300
9.10 小结 302
第10章 DSL高级定制功能 303
10.1 简介 303
10.2 定制工具 303
10.2.1 部分类 303
10.2.2 双重派生——TheGenerationGap 303
10.2.3 自定义构造函数 305
10.2.4 自定义开关 305
10.2.5 自定义重载 305
10.3 对更改的响应 306
10.3.1 属性值变化处理“OnValueChanged/Changing” 306
10.3.2 计算域属性 308
10.3.3 自定义存储域属性 309
10.3.4 值变化通知 310
10.3.5 把模型更改传递给形状:OnAssociatedPropertyChanged 311
10.3.6 规则 314
10.3.7 Store事件 318
10.3.8 NET事件处理程序 320
10.3.9 事件重载 321
10.3.10 边界规则 321
10.3.11 更改传递技术和约束技术的小结 325
10.4 DSL外壳程序体系架构 326
10.5 如何增加菜单命令 328
10.5.1 为每个命令增加一个命令标识 329
10.5.2 增量菜单资源索引 329
10.5.3 添加命令到命令集 330
10.5.4 定义命令处理程序 331
10.5.5 命令处理程序的较好实现 333
10.5.6 编译运行 333
10.5.7 为标准的命令提供处理器 333
10.6 在另一个界面中构建DSL图 334
10.7 实现复制粘贴 335
10.7.1 复制方法 336
10.7.2 粘贴方法 337
10.7.3 注册菜单处理程序 338
10.8 形状容器 340
10.8.1 子形状 340
10.8.2 使用内嵌子形状的DSL 341
10.8.3 使用规则实现形状包含 344
10.9 小结 350
第11章 设计DSL 352
11.1 简介 352
11.2 识别可变性 353
11.2.1 自底向上还是自顶向下 353
11.2.2 特征树 354
11.2.3 特征树与DSL 355
11.3 开发域模型 355
11.3.1 拟订域快照 356
11.3.2 从快照中获得的域模型 358
11.4 开发标记法 362
11.4.1 项目定义标记法 363
11.4.2 问题状态标记法 364
11.4.3 常见的标记法 367
11.5 定义验证约束 367
11.5.1 内部一致性 368
11.5.2 外部数据及模型的一致性 369
11.6 开发和演化框架 370
11.6.1 比较生成型和解释型 370
11.6.2 演化一个通用框架 372
11.6.3 从DSL驱动生成框架 373
11.7 测试 374
11.7.1 验证约束 375
11.7.2 生成器模板 376
11.7.3 生成的代码 376
11.7.4 规则 377
11.7.5 语言定义 377
11.8 改进DSL 377
11.9 什么是一个好的DSL 378
11.9.1 适当的标记法:正则表达式的一个例子 379
11.9.2 候选的标记法 380
11.9.3 图不是语法树 382
11.10 小结 383
11.11 总结 383