在本演练中,您将创建用于创建分布式应用程序(包含后端项目、用户界面项目和实用程序库)的企业级模板。本演练适用于要了解企业级模板项目原型如何简化开发分布式应用程序流程的用户,尤其适用于要开发其自己的模板来自定义 Visual Studio 集成开发环境 (IDE) 以用于自己的项目和开发组的结构设计者。
本演练包含下列部分:
开始本演练之前
规划模板的初始应用程序结构
创建初始原型
将策略与初始应用程序结构关联
将初始实现转换为模板
使模板可供用户使用
自定义策略文件
使用 ELEMENTSET 节点应用策略
开始本演练之前
在实际开始本演练之前,了解以下各点包含的建议将对您有所帮助。
打印演练
打印本演练以简化其使用。当使用单个计算机读取并执行指令时,这样做尤其有用。您将键入或复制并粘贴大量 XML,而最简单的方法是打开并打印本演练。使本演练保持打开,但使用硬拷贝遵循这些指导。如果需要复制并粘贴 XML 块,请切换到本演练,查找并复制所需的行,然后使用“编辑”菜单上的“粘贴为 HTML”进行粘贴。
查看本主题的另一种方法是在 Visual Studio 集成开发环境 (IDE) 之外显示“帮助”。从“工具”菜单中选择“选项”。从“环境”文件夹中选择“帮助”,然后选择“帮助设置”页上的“外部帮助”。请注意,仅当重新启动集成开发环境 (IDE) 后,在“设置”页上所做的更改才会生效。
确认或安装 Internet 信息服务 (IIS)
作为本演练的组成部分,您将创建一个 XML Web services。相关说明假定您所使用的开发计算机在安装 Windows 2000 或 Windows XP 的同时安装了 IIS。尽管 IIS 并非绝对必要,但是演练中某些步骤提供了基于此组件的指南。如果无法确定是否已安装此组件,则应花点时间来进行确认。
在计算机上验证和/或安装 IIS
- 在 Windows 2000 中,单击“开始”,单击“设置”,然后单击“控制面板”。(在 Windows XP 和 Windows Server 2003 中,有多种打开“控制面板”的方式,如通过“我的电脑”或直接从“开始”菜单打开。)
- 在“控制面板”中找到“添加/删除程序”图标(这在 Windows XP 和 Windows Server 2003 中称为“添加或删除程序”),双击它以显示“添加/删除程序”对话框。
- 在对话框的左侧,单击“添加/删除 Windows 组件”。
- 在“添加/删除 Windows 组件”对话框中,查找“Internet 信息服务”。如果选定了该框,则表示已经安装了 IIS,您可以跳过第 5 步和第 6 步。如果没有选定,请选择它。
- 单击“下一步”开始安装过程。
- 安装完成之后,单击“完成”,关闭向导。
在 Windows 资源管理器中显示隐藏文件、文件夹和文件扩展名
在 Windows 资源管理器中编辑文件时,如果文件和文件夹已隐藏或文件扩展名不可见,有时很难找到正确的项。验证在 Windows 资源管理器中的设置,必要时可对其进行更改。
显示隐藏文件、文件夹和文件扩展名
- 转到 Windows 资源管理器的“工具”菜单并单击“文件夹选项”,然后单击“查看”。
- 找到“隐藏文件和文件夹”,然后选择“显示隐藏文件和文件夹”。
- 找到“隐藏已知文件类型的扩展名”并清除此复选框。
本演练中的模板结构
在本演练中创建的分布式应用程序的结构将随后转化为模板,该模板由围绕后端、用户界面和实用程序库生成的结构组成。创建所需工作之后,模板就可以完全起作用了。
本演练只提供使用自定义企业级模板可以为创建分布式应用程序的开发组提供哪些服务或功能的示例。但应该切记的是,对于模板和分布式应用程序,提供的选项并不局限于在本演练中的相同选项。灵活性是企业级模板概念的重要组成部分。
规划企业级模板
本演练可以分成若干个逻辑部分,每一部分又包含几个步骤。
- 规划模板的结构并命名架构。
- 创建要保存为企业级模板的应用程序结构。
- 创建策略文件并使之与应用程序结构关联。
- 将应用程序结构和策略文件转换为企业级模板。
- 使模板可在“新建项目”对话框中供用户使用。
- 自定义模板以扩展其用途。
注意???本演练使用的名称是随意采用的,但它们都符合 DAP.tdl 文件中使用的约定。有关命名约定的更多信息,请参见企业级模板中的命名约定。
在上表中未包括一个可选逻辑部分(在第四个和第五个逻辑部分之间),即,将自定义项目向导连接到模板以生成自定义的项目文件。有关更多信息,请参见演练:使用子项目向导创建模板。
规划模板的初始应用程序结构
创建用于分布式应用程序的企业级模板的过程分为两个阶段:设计满足项目需要的应用程序结构;然后在 Visual Studio IDE 中创建该结构。即使您完全更改了自己的模板的目的和实现,也应该可以利用在此显示的结构中的概念。
模板部件的结构生成和命名
预先确定用于企业级模板中的每一对象和项目的名称非常重要。本例中,根项目为 MyTemplate。在应用程序中的其他地方不小心使用其他名称(例如 etpMyProj、etpMyProject 或 MyProj)是比较常见的错误来源。显而易见,您可以选择任意名称,但考虑使用 MyTemplate 可以增强本演练的说明效果并减少混淆。
企业级模板允许您使用两种常规项目类型:企业级模板项目(.etp 文件扩展名)和语言项目(本例为 C#)。Visual Studio 将 .etp 文件扩展名追加到每一企业级模板项目的名称之后,并提供默认的目录结构和许多企业级模板项目所必需的一组文件。以下显示了在每一企业级模板项目上的 .etp 文件扩展名和在每一 C# 语言项目上的 .csproj 文件扩展名:
????MyTemplate.etp
????????BackendProjects.etp
????????????WebService.csproj
????????UIProjects.etp
????????????WinApp.csproj
????????UtilityProjects.etp
????????????UtilityLibrary.csproj
创建这一用于模板的初始应用程序结构有多种方式。第一种方式是使用静态原型。这是最简单的过程,在本演练中用于提供对于所涉及的问题的基本了解。其他方式使用子项目向导,并提供更多的灵活性。有关更多信息,请参见演练:使用子项目向导创建模板。
创建初始原型
创建模板进程中涉及到的初始部件与创建分布式应用程序相同。在创建结构并将策略文件关联到解决方案之后,您可以编辑某些文件,并将结构优化为模板,作为将来应用程序的基础。
创建初始应用程序结构
- 启动 Visual Studio。
- 在“文件”菜单上指向“新建”,然后单击“项目”。
显示出“新建项目”对话框。
- 在“项目类型”窗格中展开“其他项目”文件夹,并选择“企业级模板项目”文件夹。“模板”窗格显示若干图标。选择“企业级模板项目”。避免双击它,以便在创建项目前可以分配自定义名称。
注意???不要在左窗格中展开“企业级模板项目”文件夹并选择其中的一个子文件夹。那些文件夹包含用作构造块而不是整个模板的语言项目。
- 使用 MyTemplate 替换默认的项目名。
- 记录“位置”中的路径名。在后面的步骤中,将把该项目复制到另一个位置。单击“确定”。MyTemplate 项目现在将出现在解决方案资源管理器中。
通过添加嵌套的 .etp 项目继续创建此模板的结构。
创建嵌套的企业级模板 (.etp) 项目
- 在解决方案资源管理器中选择 MyTemplate。
- 在“文件”菜单上指向“添加项目”,然后单击“新建项目”。
出现“添加新项目”对话框。
- 选择“企业级模板项目”,然后在“模板”窗格中选择“企业级模板项目”。
- 将项目名更改为 BackendProjects,然后单击“确定”。
解决方案资源管理器中出现 BackendProjects 项目。
- 重复该过程两次,第一次将名称更改为“UIProjects”,第二次将名称更改为“UtilityProjects”。
现在即拥有了用于分布式应用程序的模板的基本结构。
创建语言项目
现在所拥有的是大量的结构,而没有什么显而易见的功能。此模板的编程功能由基于 C# 语言的三个项目提供。这些语言项目和已经创建的企业级模板项目之间最明显的差异在于:文件扩展名和在解决方案资源管理器中与其关联的标志符号。
由于您正在创建由创建分布式应用程序的开发组所要使用的模板,因此结构将会非常复杂,这也正体现了此类项目的特性。企业级模板项目 (.etp projects) 提供了实现更加复杂的结构的方法。
创建 Asp.NET Web 服务语言项目
- 在解决方案资源管理器中选择 BackendProjects。
- 在“文件”菜单上指向“添加项目”,然后单击“新建项目”。
出现“添加新项目”对话框。
- 在“项目类型”窗格中选择“Visual C# 项目”。
- 在“模板”窗格中选择“ASP.NET Web 服务”。
- 在“位置”框中,接受或指定有效的 URL 并指定名称 WebService。单击“确定”。
WebService 项目将出现在解决方案资源管理器中。
注意???正如本演练开始所示的,您应该已在计算机上安装了 Microsoft Internet 信息服务 (IIS)。如果 IIS 安装正确,系统将自动在“位置”旁边显示 http://localhost。如果在单击“确定”后出现了错误,则检查 IIS 的安装。有关安装 IIS 的更多信息,请参见
开始本演练之前。
创建 C# Windows 应用程序语言项目
- 在解决方案资源管理器中选择 UIProjects。
- 在“文件”菜单上指向“添加项目”,然后单击“新建项目”。出现“添加新项目”对话框。
- 在“项目类型”窗格中选择“Visual C# 项目”。
- 在“模板”窗格中,选择“Windows 应用程序”。将名称更改为 WinApp,然后单击“确定”。
WinApp 项目将出现在解决方案资源管理器中。
创建 C# 类库语言项目
- 在“解决方案资源管理器”中选择 UtilityProjects。
- 在“文件”菜单上指向“添加项目”,然后单击“新建项目”。出现“添加新项目”对话框。
- 在“项目类型”窗格中选择“Visual C# 项目”。
- 在“模板”窗格中,选择“类库”。将名称更改为 UtilityLibrary,然后单击“确定”。
UtilityLibrary 项目将出现在解决方案资源管理器中。
这些原型项目用作实际应用程序的基础,您(结构设计者)可以指定应用程序的设置,例如 DefaultHTMLPageLayout 或 StartupObject。您还可以指定生成配置设置,例如 WarningLevel 或 TreatWarningsAsErrors。指定这些设置的优点是它们允许开发组使用正确的默认设置开始工作。
将策略与初始应用程序结构关联
在将此应用程序结构转换成模板之前,需要将策略文件与其关联。可从头创建策略文件,在文档中对此已作了详细介绍。有关策略文件的更多信息,请参见企业级模板策略概述。然而,在多数情况下,将策略文件与应用程序关联的最迅速且最不容易出错的方法是仅重命名 DAP.tdl 文件的一个副本,并根据需要对其进行自定义。在本演练中,可采用一个简便方法,即克隆 DAP.tdl 文件,重命名该副本,然后根据需要修改它。
将策略文件与项目关联
- 如果“属性”窗口尚不可见,请在解决方案资源管理器中选择“MyTemplate”节点(不是解决方案“MyTemplate”),右击并选择“属性”。
- 在“属性”窗口中,在网格的左列中找到“策略文件”。单击“策略文件”字段右侧的空白字段,该字段中将显示省略号按钮 (...)。
- 单击该省略号按钮打开“选择一个 TDL 文件”对话框。
- 在此对话框中,选择 DAP.tdl 文件并按 Ctrl+C 复制它。
- 按 Ctrl-V 粘贴该文件的副本,该文件副本便与其他 .tdl 文件一起显示出来。
- 右击刚创建的副本并将其重命名为 MyPolicy.tdl。
- 选择 MyPolicy.tdl 并单击“打开”,将 MyPolicy.tdl 与当前应用程序关联。
- 在系统提示重新打开项目时,单击“是”。
在“属性”窗口中,当在解决方案资源管理器中选择“MyTemplate”时,“策略文件”右侧的字段现在显示 MyPolicy.tdl。
到此时,您已创建了初始应用程序结构,该结构可以转换并另存为模板,您自己的分布式应用程序项目可基于该模板。
尽管下一节进入将应用程序转换成模板的过程,但在进入这部分过程前仍然可以向原型项目添加其他代码、控件等。您在此演练中无需这样做。
将初始实现转换为模板
对于大多数项目类型,将结构(例如在本演练中开发的这一结构)转换为模板是相当简单的。但 Web 项目(包括 Asp.NET Web 服务项目)要比其他项目类型更加复杂一点。
关闭解决方案,保存所有更改,然后在继续以下步骤之前退出 Visual Studio,以避免文件共享问题。在以下步骤中,将所创建的文件和文件夹从其当前位置复制到另一个地方,那里可以更好地反映新模板后面的逻辑。
定位模板项目文件夹和文件
组织文件夹和文件
- 查找您在 Visual Studio 中创建的初始应用程序结构的位置。MyTemplate 的默认安装点应如下所示:
C:/Documents and Settings/UserName/My Documents/Visual Studio Projects/MyTemplate
- 将整个 MyTemplate 文件夹复制到以下文件夹:
C:/Program Files/Microsoft Visual Studio .NET 2003/EnterpriseFrameworks/Projects
这将复制与 MyTemplate 关联的除 WebService 项目之外的所有文件,该项目已在其他位置创建。
- 找到 Web 根,以便确定 WebService 项目文件创建的位置。如果安装到默认位置,项目将处于以下位置:
C:/Inetpub/wwwroot/WebService
- 将 WebService 文件夹复制到位于以下位置的 BackendProjects 文件夹中:
C:/Program Files/Microsoft Visual Studio .NET 2003/EnterpriseFrameworks/Projects/MyTemplate/BackendProjects
清理项目结构
与分布式应用程序不同,模板(如您正在创建的模板)并不使用显示在项目目录结构中的所有文件和文件夹。当开发小组从模板中创建分布式应用程序时,将为特定应用程序再次创建这些文件夹和文件。因此,应移除这些文件夹和文件以避免以后发生混淆。
注意???如果尚未检查本演练开始部分提及的 Windows 资源管理器设置,则在继续操作之前请先行检查,确保 Windows 资源管理器显示所有文件、文件夹和文件扩展名。有关详细信息,请参见
开始本演练之前。
移除不必要的文件夹和文件
- 在 MyTemplate 的 .etp 项目(BackendProjects、UIProjects 和 UtilityProjects)中,子文件夹可能包含 bin 或 obj 子文件夹。您可以选择移除这些文件夹,以及移除 BackendProjects、UIProjects 和 UtilityProjects 文件夹中的任意 *.eto 文件。尽管这些文件夹并非必要,但它们的出现不会妨碍项目的功能。
- 在名为 MyTemplate 的文件夹中,删除 *.eto、*.sln 和 *.suo 文件。同样,这是一个可选步骤,这些文件并非必要,但也没有坏处。
编辑 .etp 项目文件
需要在下列文件中进行一些少量的编辑。
- .../EnterpriseFrameworks/Projects/MyTemplate/MyTemplate.etp
- .../EnterpriseFrameworks/Projects/MyTemplate/BackendProjects/BackendProjects.etp
- .../EnterpriseFrameworks/Projects/MyTemplate/UIProjects/UIProjects.etp
- .../EnterpriseFrameworks/Projects/MyTemplate/UtilityProjects/UtilityProjects.etp
移除项目 ID
除了上述所做更改之外,Web 相关的项目还需要其他修改,将 Web 项目指向驻留在您自己的项目目录结构中的副本,而不是单一的活动实例。此外,还有必要提供信息,通知企业级模板项目文件在项目初始化时提示需要 URL。
将 Web 项目修改为提示需要 URL
- 返回到 BackendProjects.etp 文件,并在“记事本”中打开它。以下显示了部分现有文本,其后显示为粗体的是做出更改的文本:
<Views>
<ProjectExplorer>
<File>http://MachineName/WebService/WebService.csproj</File>
</ProjectExplorer>
</Views>
<References>
<Reference>
<FILE>http://MachineName/WebService/WebService.csproj</FILE>
</Reference>
</References>
更改文件,即按照如下所示进行编辑并添加行:
<Views>
<ProjectExplorer>
</ProjectExplorer>
</Views>
<References>
<Reference>
</Reference>
</References> <File>WebService/WebService.csproj</File> <FILE>WebService/WebService.csproj</FILE> <REQUIRESURL>1</REQUIRESURL>
保存并关闭文件。
向项目文件添加 UserProperty 或项目全局值
下一步是为项目文件准备信息,这些信息使策略文件 MyPolicy.tdl 能够将它们识别为 ELEMENT 节点。要完成这一任务,需要向每一项目文件的 GLOBALS 部分添加 UserProperty(在语言项目中)或项目全局值(在 .etp 项目),如下所示。
下表列出了受影响的文件和必要的附加内容。您可以使用“记事本”或任意文本编辑器来做出这些更改,但在编辑策略文件时,您应该使用 Visual Studio 的 XML 设计器,充分利用其增强的功能。
文件名 |
更改 |
详细信息 |
MyTemplate.etp |
向 <GLOBALS> 节添加其他的 GLOBALENTRY 节点。 |
<GLOBALS>
<GLOBALENTRY>
<NAME>TDLFILE</NAME>
<VALUE>MyPolicy.tdl</VALUE>
</GLOBALENTRY>
<GLOBALENTRY>
<NAME>TDLELEMENTTYPE</NAME>
<VALUE>etpMyTemplate</VALUE>
</GLOBALENTRY>
</GLOBALS>
|
BackendProjects.etp |
向 <GLOBALS> 节添加其他的 GLOBALENTRY 节点。 |
<GLOBALS>
<GLOBALENTRY>
<NAME>TDLFILE</NAME>
<VALUE>MyPolicy.tdl</VALUE>
</GLOBALENTRY>
<GLOBALENTRY>
<NAME>TDLELEMENTTYPE</NAME>
<VALUE>etpBackendProjects</VALUE>
</GLOBALENTRY>
</GLOBALS>
|
UIProjects.etp |
向 <GLOBALS> 节添加其他的 GLOBALENTRY 节点。 |
<GLOBALS>
<GLOBALENTRY>
<NAME>TDLFILE</NAME>
<VALUE>MyPolicy.tdl</VALUE>
</GLOBALENTRY>
<GLOBALENTRY>
<NAME>TDLELEMENTTYPE</NAME>
<VALUE>etpUIProjects</VALUE>
</GLOBALENTRY>
</GLOBALS>
|
UtilityProjects.etp |
向 <GLOBALS> 节添加其他的 GLOBALENTRY 节点。 |
<GLOBALS>
<GLOBALENTRY>
<NAME>TDLFILE</NAME>
<VALUE>MyPolicy.tdl</VALUE>
</GLOBALENTRY>
<GLOBALENTRY>
<NAME>TDLELEMENTTYPE</NAME>
<VALUE>etpUtilityProjects</VALUE>
</GLOBALENTRY>
</GLOBALS>
|
WebService.csproj |
在 <Files></Files> 节之后以及结束 </CSHARP> 标记之前,编辑 <UserProperties> 节。 |
</Files>
<UserProperties
TDLFILE = "MyPolicy.TDL"
TDLELEMENTTYPE = "WebService"
/>
</CSHARP>
|
WinApp.csproj |
在 <Files></Files> 节之后以及结束 </CSHARP> 标记之前,编辑 <UserProperties> 节。 |
</Files>
<UserProperties
TDLFILE = "MyPolicy.TDL"
TDLELEMENTTYPE = "WinApp"
/>
</CSHARP>
|
UtilityLibrary.csproj |
在 <Files></Files> 节之后以及结束 </CSHARP> 标记之前,编辑 <UserProperties> 节。 |
</Files>
<UserProperties
TDLFILE = "MyPolicy.TDL"
TDLELEMENTTYPE = "UtilityLibrary"
/>
</CSHARP>
|
新模板现在已经就位。下一步就是使模板可用于从中创建应用程序。您首先需要让 Visual Studio 了解模板的存在,然后将其图标显示在“添加新项目”对话框中,并使用 Visual Studio?.NET 附带的用于企业级模板的图标。
使模板可供用户使用
使模板成为可见的以便它可以为其他项目轻松地发现和使用,这一点非常重要。通过创建和编辑较少的文件,您的图标就可成为“添加新项目”对话框的一部分。
创建 .vsdir 文件
Visual Studio?.NET 使用 .vsdir 文件来标识要显示在“添加新项目”对话框中的项目。.vsdir 文件中的每一行指示一个标识有效的 Visual Studio 项目的文件,包括该文件的相对路径。这些项目文件通常使用 .etp 扩展名,但它们还可使用其他扩展名,例如 .vsz(用于向导)或 .csproj(用于 Visual C# .NET 项目)。
有关 .vsdir 文件(特别是 ProxyProjects.vsdir)的更多信息,请参见 VSDir 文件和使自定义企业级模板成为新项目创建过程的默认模板的相应部分。
创建 .vsdir 文件
- 在 ../EnterpriseFrameworks/ProxyProjects 中,创建名为 UserProjects.vsdir 的 ProxyProjectsCSharp.vsdir 的副本。由于 Visual Studio 搜索带有 .vsdir 文件扩展名的所有文件,因此名称并不重要,但使用便于记忆的名称将大有帮助。
- 编辑文件(使用“记事本”或任何其他文本编辑器)删除除第一行之外的所有内容,该行如下所示:
../Projects/CSharp Simple Distributed Application/CSharp Simple Distributed Application.etp|{AE77B8D0-6BDC-11d2-B354-0000F81F0C06}|#5000|2|#5001|{AE77B8D0-6BDC-11d2-B354-0000F81F0C06}|121|0|Project
- 每一字段都使用竖线字符间隔。修改以下字段以匹配在表中指定的新值。
字段名 |
当前值 |
新值 |
RelPathName |
../Projects/CSharp Simple Distributed Application/CSharp Simple Distributed Application.etp |
../Projects/MyTemplate/MyTemplate.etp |
LocalizedName |
#5000 |
MyTemplate |
SortPriority |
2 |
0 |
Description |
#5001 |
An example user-created template |
SuggestedBaseName |
Project |
MyTemplateProject |
.vsdir 文件中的行现在应该类似于如下所示:
../Projects/MyTemplate/MyTemplate.etp|{AE77B8D0-6BDC-11d2-B354-0000F81F0C06}|MyTemplate|0|An example user-created template|{AE77B8D0-6BDC-11d2-B354-0000F81F0C06}|125|0|MyTemplateProject
本行指向 MyTemplate.etp 文件的“新建项目”对话框,标记 MyTemplate 图标,为其提供显示为“用户创建的模板示例”的说明,并为从此模板创建的任意项目分配一个默认名称。这一默认的名称是 MyTemplateProjectn(n 是 Visual Studio 分配的顺序号)。通过在 SortPriority 中指定 0,您的图标将第一个出现在可用模板的列表中。数字较大,其图标越置于列表中的较低位置。
- 保存文件更改并关闭文件。
测试到目前为止所做的工作。启动 Visual Studio 并创建一个新项目。如果您遇到错误或者只是想再次检查到目前为止所完成的工作,请参见企业级模板演练文件组 1。
使用模板创建新项目
- 在“新建项目”对话框中,选择位于企业级模板项目之下的 MyTemplate,命名 MyTemplate 项目,记录“位置”中的路径名,然后单击“确定”。
随后在项目创建期间,系统将提示您输入用于 WebService 项目的 URL 位置。
- 关闭该解决方案,保存所有更改。
自定义策略文件
如果您是用于您自己的公司或客户的分布式应用程序的结构设计者,则可能对于新的开发人员在您的开发环境中开始编写代码和在做出选择时所体现的认知难度感到无法乐观。演练的这一部分将说明如何向开发组以及您的客户提供明智的指导。通过在模板中实现策略,您可以大大降低开发人员在尝试选择最恰当的控件等对象时所花费的时间。
在 MyTemplate 中完成什么策略
通常,您可以使用策略来降低使用 MyTemplate 开发分布式应用程序的总拥有成本。完成这一目标的方法之一是提供指南,使开发人员不必选择哪些项目类型可以在您所需的结构中使用,而哪些根本就不用考虑。有关策略的更多概念性信息,请参见使用企业级模板创建分布式应用程序的优点中的相应部分。
通过确定适用于 MyTemplate 的项目类型,您可以提高工作效率,同时不会使开发人员失去对于项目的良好控制感觉。
将 ELEMENT 节点添加到策略文件
在可以使用策略为使用 MyTemplate 的开发组提供指南之前,您需要准备策略文件 (MyPolicy.tdl)。这涉及到向在新项目中标识项目的文件添加 ELEMENT 节点。
回忆对集成 TDLELEMENTTYPE 的每一项目 (每一 .etp 和 .csproj 文件)做出的最后更改。每一项目都不相同,原因在于这是您自己的特定实体,而不是一般的实体。例如,UtilityLibrary 是类库的一个实例,该类库已被重命名并且是 MyTemplate 中一个唯一的部分。由于已经向每一项目文件添加了必要的标识 (TDLELEMENTTYPE),您现在就可以编辑 MyPolicy.tdl 文件并将每一项目标识为 ELEMENT 节点。
创建标识顶级节点的 ELEMENT
- 在 Visual Studio 中,单击“文件”菜单,然后指向“打开”,再单击“文件”。
在“打开文件”对话框中,定位到“Policy”文件夹 (C:/Program Files/Microsoft Visual Studio?.NET?2003/EnterpriseFrameworks/Policy) 并打开 MyPolicy.tdl。在 Visual Studio 的 XML 设计器中打开文件可以利用其增强的功能,并且比使用常规文本编辑器效率更高。
- 在 MyPolicy.tdl 文件的起始处附近,查找 <POLICYMODE> 标记,并将属性从 PERMISSIVE 更改 RESTRICTIVE。
- 您可以移除和 DAP.tdl 文件有关的不必要的 ELEMENT 定义。搜索以下元素定义,并将每个定义连同开始的 <ELEMENT> 标记和结束的 </ELEMENT> 标记之间的内容一同删除:
- etpDistributedApplicationSimple
- etpDistributedApplicationFull
- etpBusinessFacade
- etpBusinessRules
- etpDataAccess
- etpSystem
- etpWebService
- etpWebUI
- etpWinUI
- projBusinessFacade
- projBusinessRules
- projDataAccess
- projSystem
- projWebService
- projWebUI
- projWinUI
- 确定一个方便的位置,将编辑信息插入到 MyPolicy.tdl 文件中。在文件的起始处是一个 ELEMENT 定义示例。滚动到示例的末尾,将以下 TDL 行添加到 MyPolicy.tdl。您可能希望逐个字符键入这些行,但为了简化流程,您可以从此文档复制这些行,并将其粘贴到 MyPolicy.tdl。粘贴这些行时,使用“编辑”菜单上的“粘贴为 HTML”命令。
注意???在插入点添加注释很有帮助,在日后可以方便地找到相应位置。
<ELEMENT>
<ID></ID>
<IDENTIFIERS>
<IDENTIFIER>
<TYPE></TYPE>
<IDENTIFIERDATA>
<NAME></NAME>
<VALUE></VALUE>
</IDENTIFIERDATA>
</IDENTIFIER>
</IDENTIFIERS>
<ELEMENTSET>
<DEFAULTACTION></DEFAULTACTION>
<ORDER></ORDER>
</ELEMENTSET>
<PROTOTYPES>
<PROTOTYPE>
</PROTOTYPE>
</PROTOTYPES>
</ELEMENT>etpMyTemplatePROJECTGLOBAL:TDLELEMENTTYPEetpMyTemplateINCLUDEINCLUDEEXCLUDE[EF]/Projects/MyTemplate/MyTemplate.etp
注意???粗体项专门应用于此 ELEMENT。
这些 TDL 行将指定以下内容:
TDL 节点 |
说明 |
ID |
用于可在策略文件中其他点引用的 ELEMENT 的唯一标识符。 |
TYPE |
指定该元素是项目、项目项、引用、代码、代码变量还是 HTML 实体。指定的 TYPE 确定哪些名称可以作为策略文件的 IDENTIFIERDATA 节中名称/值对的一部分。 |
IDENTIFIERDATA |
引用在策略文件中标识为 ELEMENT 的特定项目的名称/值对。这是用于此 ELEMENT 全局标识符。例如,要查找此 ELEMENT,可以查找包含全局值或名为 TDLELEMENTTYPE 的 UserProperty(值为 etpMyTemplate)的项目。 |
ELEMENTSET |
尽管在此节点中可以包括更多信息,但 DEFAULTACTION 和 ORDER 只指定了限制用户将项目类型添加为 MyTemplate 的子节点所必需的标准。由于 DEFAULTACTION 指定 INCLUDE,而 ORDER 指定 INCLUDEEXCLUDE,此时没有显示限制。 |
PROTOTYPE |
提供此 ELEMENT 在目录结构中的相对位置。 |
这为您必需提供给其余项目的信息提供了一种模式。这些信息创建项目文件和策略文件之间的关联。建立了关联后,可以为使用此模板创建应用程序的开发人员提供指南。有关更多信息,请参见 TDL 中的 ELEMENTS 和 ELEMENT 节点。
创建标识其余企业级模板 (.etp) 项目的 ELEMENT 节点
创建标识每个 Visual C# 项目 (.csproj) 的 ELEMENT 节点
接下来,为三个语言项目提供 ELEMENT 定义:WebService、WinApp 和 UtilityLibrary。
注意???由于元素名称在策略文件中必须是唯一的,请从 MyPolicy.tdl 删除现有的“projWebService”的 ELEMENT 定义(您将要创建自己的 projWebService 元素定义)。
要减少出错的可能性,您可以从此文档复制一些行,并将其粘贴到 MyPolicy.tdl,但您也可以复制并修改现有的 ELEMENT 定义,例如 projBusinessFacade。
注意???粘贴这些行时,请使用“编辑”菜单上的“粘贴为
HTML”。
这三个语言项目的 ELEMENT 定义应该如下所示。
<ELEMENT>
<ID>projWebService</ID>
<IDENTIFIERS>
<IDENTIFIER>
<TYPE>PROJECT</TYPE>
<IDENTIFIERDATA>
<NAME>GLOBAL:TDLELEMENTTYPE</NAME>
<VALUE>WebService</VALUE>
</IDENTIFIERDATA>
</IDENTIFIER>
</IDENTIFIERS>
<PROTOTYPES>
<PROTOTYPE>
[EF]/Projects/MyTemplate/BackendProjects/WebService/WebService.csproj
</PROTOTYPE>
</PROTOTYPES>
<ELEMENTSET>
<DEFAULTACTION>INCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
</ELEMENTSET>
</ELEMENT>
<ELEMENT>
<ID>projWinApp</ID>
<IDENTIFIERS>
<IDENTIFIER>
<TYPE>PROJECT</TYPE>
<IDENTIFIERDATA>
<NAME>GLOBAL:TDLELEMENTTYPE</NAME>
<VALUE>WinApp</VALUE>
</IDENTIFIERDATA>
</IDENTIFIER>
</IDENTIFIERS>
<PROTOTYPES>
<PROTOTYPE>
[EF]/Projects/MyTemplate/UIProjects/WinApp/WinApp.csproj
</PROTOTYPE>
</PROTOTYPES>
<ELEMENTSET>
<DEFAULTACTION>INCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
</ELEMENTSET>
</ELEMENT>
<ELEMENT>
<ID>projUtilityLibrary</ID>
<IDENTIFIERS>
<IDENTIFIER>
<TYPE>PROJECT</TYPE>
<IDENTIFIERDATA>
<NAME>GLOBAL:TDLELEMENTTYPE</NAME>
<VALUE>UtilityLibrary</VALUE>
</IDENTIFIERDATA>
</IDENTIFIER>
</IDENTIFIERS>
<PROTOTYPES>
<PROTOTYPE>
[EF]/Projects/MyTemplate/UtilityProjects/UtilityLibrary/UtilityLibrary.csproj
</PROTOTYPE>
</PROTOTYPES>
<ELEMENTSET>
<DEFAULTACTION>INCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
</ELEMENTSET>
</ELEMENT>
注意您还在使用同一类型的标识(项目全局)并指向每一用例中的语言项目原型。
继续进行之前,关闭并保存 MyPolicy.tdl。
验证 MyPolicy.tdl 的更改
现在可以验证对于 MyPolicy.tdl 所做的更改是否显示在 Visual Studio 集成开发环境 (IDE) 中。请记住,您尚未设置任何策略,但已将项目标识为 ELEMENT 节点。验证这些标识后,可以在 MyPolicy.tdl 中进行一些调整,为使用 MyTemplate 的开发组提供实际的指南。
检查策略文件的更改结果
- 转至“文件”菜单,选择“新建”,然后单击“项目”。显示出“新建项目”对话框。
- 在“项目类型”窗格中,展开“其他项目”,然后单击“企业级模板项目”。
- 在“模板”窗格中,选择“MyTemplate”,接受默认的项目名,然后单击“确定”。如果策略文件中有输入错误,则会在重新加载时在任务列表中出现错误信息。仔细阅读错误信息,然后打开策略文件进行必要的编辑。解决所有的加载错误之后,就可以检查更改的结果了。
- 在“解决方案资源管理器”中选择顶级项目,然后在“属性”窗口中检查。
“元素”属性具有的值与在上述 MyPolicy.tdl 中为 ELEMENT 提供的 ID 相匹配。展开 Elements 和 Instances 节点。注意,当前选择与 ELEMENT etpMyTemplate 的标识匹配,使用的标识是 GLOBAL:TDLELEMENTTYPE。在 Instances 部分,所选项是名为 MyTemplateProjectn.etp 的项目,其中 n 是由 Visual Studio 分配给最新的 MyTemplateProject.etp 的顺序号。
- 在解决方案资源管理器中选择其他每一节点。注意“元素”字段中的以下内容:
解决方案资源管理器所选内容 |
元素值 |
MyTemplateProjectn |
etpMyTemplate |
BackendProjects |
etpBackendProjects |
WebService |
projWebService,projCSharpProject |
UIProjects |
etpUIProjects |
WinApp |
projWinApp,projCSharpProject |
UtilityProjects |
etpUtilityProjects |
UtilityLibrary |
projUtilityLibrary,projCSharpProject |
- 如果选择语言项目(项目项)中的节点,将会看到 MyPolicy.tdl(从 DAP.tdl 文件复制并重命名)中的其他定义,这些定义标识每个文件类型,并将其与适当 ELEMENT 关联,如下所示。
解决方案资源管理器所选内容 |
元素值 |
WebService/AssemblyInfo.cs |
projItemCSharpFile |
WebService/Global.asax |
ProjItemGlobalApplicationClass |
WebService/Service1.asmx |
projItemWebService |
WebService/Web.Config |
projItemWebConfigFile |
WinApp/AssemblyInfo.cs |
projItemCSharpFile |
WinApp/Form1.cs |
projItemCsharpFile,codeWinForm,codeComponent |
UtilityLibrary/AssemblyInfo.cs |
projItemCSharpFile |
UtilityLibrary/Class1.cs |
projItemCSharpFile |
注意???Form1.cs 映射到多个 ELEMENT 节点。它是一个 Visual
C# 文件,并且包含 Windows 窗体。由于 WindowsForm 类是从自定义控件 (Custom Control) 类中派生,因此它也被标识为自定义控件 (Custom Control)。
您现在可以添加一些限制,例如在模板中的各个位置可以添加哪些内容。通过向 MyPolicy.tdl 中的 ELEMENTSET 定义中添加信息即可完成这一目的。
如果要再次检查到目前为止所做的工作,请参见企业级模板演练文件组 2。
使用 ELEMENTSET 节点应用策略
为确保提供给开发组的模板以最有效的方式优化,并且没有为开发人员附加执行任务的限制,在此时进行规划就愈加体现其重要性了。构建一个类似如下的表,这样可有助于确定您的策略要建立哪些类型的规则。
策略规划表
ELEMENT |
规则 |
etpMyTemplate |
只允许您此前定义为子级的企业级模板项目(BackendProjects、UIProjects 和 UtilityProjects)。 |
etpBackendProjects |
允许 WebService 项目,以及 C# 类库和 C# 空项目项目。您不希望用户添加标准的 C# Asp.NET Web 服务,原因是最终将因此具有更多的初始代码。 |
etpUIProjects |
允许 WinApp 项目,以及 C# Windows 应用程序和 C# 空项目项目。 |
etpUtilityProjects |
允许 UtilityLibrary 项目,以及 C# 类库和空项目项目。 |
projWebService |
您不希望 BackendProjects WebService 项目包含任何 Web UI 项,因此在项目中限制这些项。使用预定义的 CATEGORY 节点(最初复制自 DAP.tdl)来使 MyPolicy.tdl 中的 TDL 更加简明易读。 |
projWinApp |
允许 Windows UI 控件、公共项、Windows UI 代码项和工具箱组件。同上,使用预定义的 CATEGORY 节点(最初复制自 DAP.tdl)来使 MyPolicy.tdl 中的 TDL 更加简明易读。 |
projUtilityLibrary |
允许可在 WebService 项目中使用的相同的项,以及工具箱数据项。 |
模板描述语言使用 ELEMENTSET 作为其主要的机制之一来允许项目和项目项供人使用(或限制使用)。结构设计者可以进行挑选以减少不必要的选项。如上表所示,允许在此特定模板的结构中使用的项目类型已经非常明确了,因此您可以默认排除所有的项目类型。然后,可以按照名称包括明确要提供给模板用户使用的项目类型。有关 ELEMENTSET 节点的更多信息,请参见 TDL 中的 ELEMENTSET 节点。
更新 etpMyTemplate 的 ELEMENTSET 节点
要更新 ELEMENT etpMyTemplate 的 ELEMENTSET 定义,可编辑 ELEMENTSET 来最初排除所有项目类型,方法是将 DEFAULTACTION 设置为 EXCLUDE。通过将 ORDER 设置为 INCLUDEEXCLUDE,包含在 ELEMENTSET 中的 INCLUDE 标记中的项目类型将会得到评估和批准。最后,为指定要允许作为子级的项目,需要在 INCLUDE 节点中对其逐个进行标识。
更新 etpMyTemplate 的 ELEMENTSET 节点
- 在 MyPolicy.tdl 中,定位 etpMyTemplate ELEMENT 的 ELEMENTSET 节点。
- 修改 ELEMENTSET 定义,将 DEFAULTACTION 设置为 EXCLUDE,以允许在规划表中指定的三个 .etp 项目作为 etpMyTemplate 的子级。对 ELEMENTSET 节点的更改应与以下内容一致。
<ELEMENTSET>
<DEFAULTACTION></DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
</ELEMENTSET>EXCLUDE <INCLUDE>etpBackendProjects</INCLUDE> <INCLUDE>etpUIProjects</INCLUDE> <INCLUDE>etpUtilityProjects</INCLUDE>
更新嵌套在 etpMyTemplate 下的 ELEMENT 节点的 ELEMENTSET 节点
通过编辑属于 etpMyTemplate 的 ELEMENTSET 节点,策略文件现在已符合上述策略规划表的第一行中列出的规则。现在可以更新已包含在 etpMyTemplate 的子级中的三个 ELEMENT 节点的 ELEMENTSET 节点:
- etpBackendProjects
- etpUIProjects
- etpUtilityProjects
更新 ELEMENTSET 节点,通过默认设置排除所有的项目类型,只允许在规划表的相应行中指定的项目类型作为这三个 ELEMENT 节点的子级。下列过程提供 TDL 行,这些 TDL 行通过将 DEFAULTACTION 设置为 EXCLUDE 并添加适当的 INCLUDE 节点来进行这些更新。
更新三个剩余 .etp 项目的 ELEMENTSET 节点
- 使用以下所示内容替换现有的 etpBackendProjects ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>projWebService</INCLUDE>
<INCLUDE>projCSharpProject</INCLUDE>
<INCLUDE>projCSharpEmptyProject</INCLUDE>
</ELEMENTSET>
此 ELEMENTSET 的基本原理和属于顶级节点 (etpMyTemplate) 的 ELEMENTSET 的基本原理完全相同。使用 EXCLUDE 作为默认设置可以大大简化所要实施的约束。
- 使用以下所示内容替换现有的 etpUIProjects ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>projWinApp</INCLUDE>
<INCLUDE>projCSharpWinApp</INCLUDE>
<INCLUDE>projCSharpProject</INCLUDE>
<INCLUDE>projCSharpEmptyProject</INCLUDE>
</ELEMENTSET>
- 使用以下所示内容替换现有 etpUtilityProjects ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>projUtilityLibrary</INCLUDE>
<INCLUDE>projCSharpClassLibrary</INCLUDE>
<INCLUDE>projCSharpProject</INCLUDE>
<INCLUDE>projCSharpEmptyProject</INCLUDE>
</ELEMENTSET>
更新其余的 ELEMENTSET 节点
其余的 ELEMENT 节点都是语言项目。尽管模板的结构由企业级模板项目(.etp 文件)提供,但实际的工作是在语言项目中完成的。这些项目的 ELEMENTSET 定义差别较大。当开发组成员从模板创建应用程序时,必须向他们提供各种控件、工具等等。
可以列出要提供开发组使用的每一项,方法是在 ELEMENTSET 中 INCLUDE 标记内放置每一项的正确名称,但由于存在如此之多的项目项,这将会花费大量的时间。另外有一种方法,使用您在创建 MyPolicy.tdl 时所复制的 DAP.tdl 文件的功能。MyPolicy.tdl 已经包含各个 CATEGORY 节点,这些节点由几乎可以引用所有所需功能的逻辑组构成。通过在以下步骤中搜索 INCLUDE 节点中显示的类别名的文件,您可以找到 CATEGORY 的定义。
更新 ELEMENTSET 节点,按照默认设置排除所有的项目项,然后包括所需的类别。下列过程提供 TDL 行,这些 TDL 行通过将 DEFAULTACTION 设置为 EXCLUDE 并添加适当的 INCLUDE 节点来进行这些更新。
更新语言项目的 ELEMENTSET 节点
- 使用以下所示内容替换 projWebService ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>catVBCommonProjectItems</INCLUDE>
<INCLUDE>catCommonProjectItems</INCLUDE>
<INCLUDE>catCSCommonProjectItems</INCLUDE>
<INCLUDE>catComponentCodeItems</INCLUDE>
<INCLUDE>catWebConfigurationProjectItems</INCLUDE>
<INCLUDE>projItemWebService</INCLUDE>
<INCLUDE>projItemGlobalApplicationClass</INCLUDE>
<INCLUDE>codeWebService</INCLUDE>
<INCLUDE>refSystem.Web</INCLUDE>
<INCLUDE>refSystem.Web.Services</INCLUDE>
</ELEMENTSET>
注意???为了在 Visual Studio 任务列表中避免出现策略提醒,INCLUDE 节点指定了
Asp.NET
Web 服务项目(Web.config 和全局应用程序类项)的标准部分。
- 使用以下所示内容替换 projWinApp ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>catVBCommonProjectItems</INCLUDE>
<INCLUDE>catWinUIProjectItems</INCLUDE>
<INCLUDE>catCommonProjectItems</INCLUDE>
<INCLUDE>catCSCommonProjectItems</INCLUDE>
<INCLUDE>catWinCodeItems</INCLUDE>
<INCLUDE>catDataCodeItems</INCLUDE>
<INCLUDE>catComponentCodeItems</INCLUDE>
<INCLUDE>refSystem.Windows.Forms</INCLUDE>
</ELEMENTSET>
- 使用以下所示内容替换 projUtilityLibrary ELEMENTSET:
<ELEMENTSET>
<DEFAULTACTION>EXCLUDE</DEFAULTACTION>
<ORDER>INCLUDEEXCLUDE</ORDER>
<INCLUDE>catVBCommonProjectItems</INCLUDE>
<INCLUDE>catCommonProjectItems</INCLUDE>
<INCLUDE>catCSCommonProjectItems</INCLUDE>
<INCLUDE>catComponentCodeItems</INCLUDE>
<INCLUDE>catWebConfigurationProjectItems</INCLUDE>
<INCLUDE>projItemWebService</INCLUDE>
<INCLUDE>projItemGlobalApplicationClass</INCLUDE>
<INCLUDE>codeWebService</INCLUDE>
</ELEMENTSET>
将这些更改保存到 MyPolicy.tdl,然后关闭当前项目并重新打开 MyTemplate 项目。这将允许您轻松检查可能发生的键入错误。检查任务列表中是否有错误,如有必要则进行更正。
如果遇到错误或者只是想复查您的工作,请参见企业级模板演练文件组 3。
检查策略的效果
您可以查看刚刚应用到新模板的策略对“添加新项目”对话框有何影响。在对节点应用策略的前后比较此对话框的内容。
查看策略的效果
- 在“解决方案资源管理器”中,右击“解决方案”节点,指向“添加”,然后单击“新建项目”。您将会在“添加新项目”对话框中看到可用项目的完整集合。单击“取消”关闭对话框。
- 重复该过程,在“解决方案资源管理器”中选择各个项目节点,检查在“添加新项目”对话框中可用的项目。注意项目集现已受到限制。随后,在定义 WebService 的构造块时,将看到 WebService 项目可用。
即使已经通过策略表示您允许在开发人员在使用 MyTemplate 时将新的模板和语言项目添加到所编写的任意应用程序中,但 Visual Studio IDE 仍然无法意识到这些项目的存在。尽管您可以在解决方案资源管理器中看到这些项的图形表示,但对于要添加到现有应用程序的构造块来说,您需要对 .vsdir 文件做一些更改并添加一些内容。