如何:生成 .NET 代码的依赖项关系图
若要浏览 .NET 代码中的组织和关系,请使用 Visual Studio 旗舰版生成依赖项关系图。 使用这些关系图可帮助您直观显示、浏览和分析代码中的依赖项。 关系图将代码元素及其关系表示为一组由链接或边缘连接的节点。
提示
如果您的解决方案非常大,则生成依赖项关系图可能会导致出现内存不足异常。 如果出现了此异常,请缩小解决方案的范围。 您还可使用体系结构资源管理器来选择您要直观显示的项目和依赖项,然后生成关系图。
若要生成 C 和 C++ 代码的依赖项关系图以及 Web 项目的依赖项关系图,请下载并安装Microsoft Visual Studio 2010 可视化和建模功能包。
有关更多信息,请参见:
选择要生成的依赖项关系图
利用 Visual Studio 旗舰版,您可快速生成关系图文档以浏览代码中的依赖项。若要使用命令行工具生成关系图文档,请参见生成关系图文档以进行批处理。
若要 |
生成显示以下关系的关系图 |
---|---|
查看源代码概述 |
Visual Studio 解决方案中的所有程序集、所有命名空间或所有类之间的关系。 关系图显示所选节点的顶层的聚合依赖关系。 |
查看源代码中的特定依赖关系 |
Visual Studio 解决方案中源代码的所选区域之间的关系。 使用“体系结构资源管理器”可分层浏览代码,并选择特定种类的结构和关系。 |
查看已编译代码概述 |
一个或多个 .NET 程序集 (.dll) 文件或可执行 (.exe) 文件中的关系 |
查看已编译代码中的特定依赖关系 |
.NET 程序集 (.dll) 或可执行 (.exe) 文件中所选区域之间的关系。 使用“体系结构资源管理器”可浏览并选择特定种类的结构和关系。 |
生成关系图后,您便可使用它以不同方式浏览代码。 有关更多信息,请参见如何:使用依赖项关系图浏览代码。
查看 Visual Studio 解决方案中的源代码概述
打开此解决方案。
在**“体系结构”菜单中,指向“生成依赖项关系图”**,然后执行下列步骤之一:
单击
生成显示以下各项的关系图
按程序集
解决方案生成的所有程序集和它们所依赖的任何外部依赖项之间的聚合依赖关系。
若要查看某个程序集内的命名空间、类和方法,请在关系图上展开该程序集。 外部程序集仅显示正在使用的项。
按命名空间
解决方案中所有命名空间和代码所依赖的任何外部命名空间之间的依赖关系。
若要查看某个命名空间内的类和方法,请在关系图上展开该命名空间。 外部命名空间仅显示正在使用的项。
按类
解决方案中所有类之间的聚合依赖关系。 将不会显示有关代码使用的外部类的信息。
- 或 -
若要查看多种类型的结构之间的依赖关系,请单击**“自定义”**。
在**“生成依赖项关系图”对话框中,至少单击以下各个框之一:“程序集”、“命名空间”、“类型”或“方法”**。
使用下表来筛选关系图:
若要
执行这些步骤
查看对外部依赖关系的引用。
在了解内部程序集如何基于外部程序集生成时,这一点非常有用。
选择“外部”
仅查看具有特定访问级别的类型和方法。
例如,您可能希望通过仅选择公共类型来简化关系图。
展开“访问筛选器”窗格,然后选择所需的级别。
注意至少必须选择一个类型访问级别。若要减少关系图上依赖项的数量,请仅为方法选择所需的访问级别。通过将包容关系显示为嵌套组并将依赖关系显示为聚合链接,从而查看高级别依赖关系。
注意对于方法,依赖关系将显示为单独的链接(而不是聚合链接),因为方法是最低级别的叶节点。选中“包容显示为组”框。
通过将包容关系显示为链接的节点并将依赖关系显示为单独的链接,从而查看低级别依赖关系。
清除“包容显示为组”框。
完成上述操作后,单击**“确定”**。
Visual Studio 将创建一个定向关系图文档(.dgml 文件)并打开该文档。
聚合依赖关系的链接的粗细大致指示了该聚合依赖关系表示多少单独的依赖关系。 若要查看链接表示的依赖关系的种类,请将指针移到链接上,直至出现工具提示。
提示
从“体系结构”菜单生成的依赖项关系图不显示对虚方法的调用(下至派生程度最大的类型)。 相反,这些关系图将显示对用于声明虚拟成员的类型的依赖项。 但您可以使用“体系结构资源管理器”中的“类视图”来查找这些调用。 然后,可以将这些调用从“体系结构资源管理器”拖动到现有关系图中,也可以从“体系结构资源管理器”工具栏生成新的关系图。
查看 Visual Studio 解决方案中的源代码中的特定依赖关系
使用**“体系结构资源管理器”**可查找需要可视化的代码和关系。 还可以使用预定义的查询来生成关系图。
打开此解决方案。
如果**“体系结构资源管理器”未打开,则在“体系结构”菜单上,指向“窗口”,然后单击“体系结构资源管理器”**。
在**“体系结构资源管理器”的第一列中的“Visual Studio”**下,单击以下视图之一:
单击**“类视图”**以浏览代码的逻辑层次结构。
用于浏览命名空间、类型、方法等。
单击**“解决方案视图”**以浏览代码的物理层次结构
用于浏览项目、源文件等。
在下一列中,选择要浏览的项。 若要选择该列中的所有内容,请按 Ctrl+A。
下一列将根据该列中项和关系的默认种类显示与所选内容相关的项。
提示
若要选择其他种类的项和关系,请展开包含所选内容的列右侧的折叠的列。 在“节点导航”下,选择所需的项的种类。 在“出站导航”或“入站导航”下,选择所需的关系的种类。 有关更多信息,请参见如何:使用体系结构资源管理器查找代码。
重复步骤 4,直至选择了所有需要的项。
提示
若要在关系图上包括“调用”依赖关系,请浏览到所选类调用的所有方法,并选择这些方法。
若要基于所选内容创建新的关系图,请在**“体系结构资源管理器”标题栏下方,单击“基于所选的全部节点创建一个新的关系图文档”**。
Visual Studio 将创建一个定向关系图文档(.dgml 文件)并打开该文档。
- 或 -
若要将所选内容添加到现有关系图或空白关系图,请执行以下步骤:
打开现有关系图的 .dgml 文件,或创建空白关系图。
在**“体系结构资源管理器”标题栏下方,单击“将所选的全部节点添加到当前可见的关系图文档”**。
- 或 -
将节点从**“体系结构资源管理器”**拖到关系图上。
创建空白关系图
若要打开空白关系图,请在**“文件”菜单上指向“新建”,然后单击“文件”**。
- 或 -
若要将空白关系图添加到**“解决方案项”文件夹,请在“解决方案资源管理器”中右击顶级解决方案节点,然后单击“添加新项”**。
在**“已安装的模板”下单击“常规”**。
在右边的窗格中,单击**“定向关系图文档”,为关系图命名,然后单击“添加”**。
有关可与关系图交互的不同方式的更多信息,请单击空白关系图上显示的帮助链接。
使用预定义的查询浏览源代码
打开此解决方案。
如果**“体系结构资源管理器”未打开,则在“体系结构”菜单上,指向“窗口”,然后单击“体系结构资源管理器”**。
在**“体系结构资源管理器”的第一列中的“已保存的 DGQL 查询”下,单击“在文件夹中”**。
在下一列中,根据所需创建的关系图的种类,单击以下查询之一:
生成显示以下各项的关系图
单击
解决方案引用的所有程序集。
从查询结果中,您可以生成显示这些程序集之间的依赖关系的关系图。
All Assembly References.dgql
解决方案中没有依赖项链接的所有输出程序集的简单列表。
All Output Assemblies.dgql
若要为所选程序集生成标准依赖项关系图,请执行以下步骤:
在下一列中,选择所需的程序集。
在当前列的右侧,单击折叠的操作列将其展开。
注意将指针移到“操作”列上时,该列会突出显示。在“操作”列的“命令”下,单击“标准关系图”。
解决方案中的所有项目。
从查询结果中,您可以生成显示这些项目之间的引用的关系图。
All Project References.dgql
解决方案中的所有项目的简单列表。
如果您的解决方案包括解决方案文件夹,则此列表与在体系结构资源管理器中单击“解决方案视图”时显示的列表不同。
All Projects.dgql
解决方案中的所有类型。
从查询结果中,您可以生成显示这些类型之间的继承关系的关系图。
Inheritance Graph.dgql
下一列将以简单列表的形式显示结果。 尽管这些节点之间可能存在链接,但**“体系结构资源管理器”**将不会显示这些链接。
若要为结果列中的所有项生成关系图(包括链接),请执行以下步骤:
在结果列中,按 Ctrl+A 选择所有项。
按住 Ctrl 键以仅在关系图上包括当前列中的项,然后在**“体系结构资源管理器”标题栏的下方,单击“基于所选的全部节点创建一个新的关系图文档”**。
Visual Studio 将创建一个定向关系图文档(.dgml 文件)并打开该文档。
查看已编译代码概述
创建空白关系图,或打开现有关系图的 .dgml 文件。
从 Visual Studio 外将 .dll 文件或 .exe 文件拖到关系图上。
提示
不支持从“解决方案资源管理器”的“引用”文件夹中拖动。 只有在按相同的用户访问控制 (UAC) 权限级别运行 Windows 资源管理器和 Visual Studio 时,才能从 Windows 资源管理器中拖动程序集。 例如,如果启用了 UAC,并且您正在以管理员身份运行 Visual Studio,则 Windows 资源管理器将阻止拖动操作。 若要解决此问题,请禁用 UAC 或使用预定义的查询来浏览解决方案。
查看已编译代码中的特定依赖关系
如果**“体系结构资源管理器”未打开,则在“体系结构”菜单上,指向“窗口”,然后单击“体系结构资源管理器”**。
在第一列中的**“文件系统”下,单击“选择文件”**。
在**“打开”**框中,浏览到 .dll 文件或 .exe 文件以选择并打开这些文件。
在下一列中,选择程序集。 若要选择该列中的所有内容,请按 Ctrl+A。
下一列将根据该列中项和关系的默认种类显示与所选内容相关的项。
提示
若要选择其他种类的项和关系,请展开包含所选内容的列右侧的折叠的列。 将指针移到“操作”列上时,该列会突出显示。 在“节点导航”下,选择所需的项的种类。 在“出站导航”或“入站导航”下,选择所需的关系的种类。 有关更多信息,请参见如何:使用体系结构资源管理器查找代码。
选择以下选项之一:
基于以下各项创建依赖项关系图
请执行这些步骤
程序集
在包含程序集的列的右侧,单击折叠的操作列将其展开。
将指针移到“操作”列上时,该列会突出显示。
在“操作”列的“命令”下,单击“标准关系图”。
类和方法
浏览类和方法,同时选择要包括在关系图上的所有项。
若要创建新的关系图,请在“体系结构资源管理器”标题栏下方,单击“基于所选的全部节点创建一个新的关系图文档”。
Visual Studio 将创建一个定向关系图文档(.dgml 文件)并打开该文档。
- 或 -
若要将所选内容添加到现有关系图或空白关系图,请执行以下步骤:
打开现有关系图的 .dgml 文件,或创建空白关系图。
在“体系结构资源管理器”标题栏下方,单击“将所选的全部节点添加到当前可见的关系图文档”。
- 或 -
将节点从“体系结构资源管理器”拖到关系图上。
生成关系图文档以进行批处理
若要以批处理模式生成关系图文档(.dgml 文件),请使用 GraphCmd.exe 命令行工具。 例如,通过在每次生成后运此工具,可查找各个生成之间的已更改的依赖关系。
若要查找此工具,请在以下文件夹中进行查找:C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE。
提示
GraphCmd.exe 仅生成程序集或 .dgml 文件的依赖项信息,而不生成 Visual Studio 解决方案或项目文件中的源代码。
GraphCmd.exe 的语法为:
GraphCmd -? -all -exceptions -input File_Name -query File_Name -exec
"DGQL_Statement" -output File_Name -path alias=path
下表描述 GraphCmd.exe 的选项:
-? |
显示 GraphCmd.exe 的帮助信息。 |
-all |
包括所有中间查询结果,而不仅仅是最后一个节点集的中间查询结果。 |
-exceptions |
以关系图文档 (.dgml) 文件的形式报告查询异常。 |
-input File_Name |
处理指定的 .dgml 文件。 这可用于后期处理大型 .dgml 文件并对其进行筛选,以便能够在 Visual Studio 中更轻松地对该文件进行可视化。 |
-query File_Name |
运行指定的定向关系图查询语言(DGQL 或 .dgql)文件。 有关更多信息,请参见:
|
-exec "DGQL 语句" |
运行指定的 DGQL 语句。 有关更多信息,请参见了解定向关系图查询语言 (DGQL)。 |
-output File_Name |
输出指定的 .dgml 文件。 |
-path alias=path |
指定一个在 DGML 文档的输入和输出中使用的新别名。 例如:
有关更多信息,请参见常用路径的别名。 |
备注
由于 GraphCmd.exe 是在 Visual Studio 外部运行的,因此对 .dgql 查询中的操作的支持是有限的。
可以多次指定下列选项:-input、-query、-exec 和 -path。
常用路径的别名
常用路径的别名将减小 .dgml 文件的大小,并减少加载或保存该文件所需的时间。 若要创建别名,请在 .dgml 文件的结尾处添加 <Paths></Paths> 部分。 在此部分添加 <Path/> 元素以定义路径的别名:
<Paths>
<Path Id="MyPathAlias" Value="C:\...\..." />
</Paths>
若要从 .dgml 文件中的某个元素引用别名,请用美元符号 ($) 和括号 (()) 将 <Path/> 元素的 Id 括起来。
<Nodes>
<Node Id="MyNode" Reference="$(MyPathAlias)MyDocument.txt" />
</Nodes>
<Properties>
<Property Id="Reference" Label="My Document" DataType="System.String" IsReference="True" />
</Properties>
有关编辑 .dgml 文件的更多信息,请参见如何:编辑和自定义关系图文档。
了解定向关系图查询语言 (DGQL)
DGQL 是一种可用于生成 DGML 的轻量查询语言。 DGQL 语句遵循以下节点选择和操作的交替模式:每个节点选择为下一个操作创建输入,而下一个操作的输出将成为下一个节点选择的输入,依此类推。
DGQL 语句的格式为:
<node selection> / <action> / <node selection> / <action> / ...
下表描述用于选择节点的 DGQL 语法:
* |
选择所有节点。 |
+ "text" |
选择所有包含“text”的节点。 |
+ Id.Equals("text") |
选择所有其 Id 等于“text”的节点。 |
+ Background.Contains("text") |
选择所有其 Background 特性具有包含字符串“text”的值的节点。 |
+ "text1" + "text2" + ... |
选择所有匹配“text1”或“text2”的节点。 |
+ MyProperty="True" |
选择所有具有名为 MyProperty 的属性(其值为“True”)的节点。 |
- Label.Contains("text") |
选择所有节点,具有包含 (Contains) 字符串“text”的 Label 特性的节点除外。 |
+ Category.Is("MyCategory") |
选择所有具有名为 MyCategory 的类别的节点或从 MyCategory 继承的节点。 |
虽然这些操作是由已在 Visual Studio 中注册的 DGML 数据提供程序提供的,但可以通过保存在体系结构资源管理器中创建的查询来发现它们。 有关使用体系结构资源管理器的更多信息,请参见如何:使用体系结构资源管理器查找代码。
下表描述了可对所选节点执行的直接操作的示例:
示例操作 |
说明 |
---|---|
Microsoft.Contains |
返回输入节点所包含的所有节点。 可以将 Contains 替换为一个不同的链接类别。 |
Microsoft.Open |
打开输入节点的源代码。
注意
此操作仅在 Visual Studio 中有效。
|
Microsoft.AllOutBoundLinks |
返回作为来自输入节点的传出链接的目标的所有节点。 |
Microsoft.AllInboundLinks |
返回作为指向输入节点的链接的源端的所有节点。 |
Microsoft.Core.CreateGroupsByProperties |
调用 GroupByProperties 操作。 |
Microsoft.AllNodes |
返回目前为止整个关系图中包含的所有节点。 |
数据驱动的操作仅基于输入节点和链接中的数据选择项。 在使用数据驱动的操作匹配类别时,将包含继承的类别。 下表描述数据驱动的操作的示例:
类型 |
说明 |
---|---|
Node:Both:Category |
返回具有类别 Category 并通过指向任一方向的链接与输入节点连接的所有节点。 |
Link:Both:Category |
返回通过指向任一方向的链接与输入节点连接并具有类别 Category 的所有节点。 |
Link:Backward:Category |
返回利用具有类别 Category 的链接指向输入节点的所有节点。 |
Link:Forward:Category |
返回利用具有类别 Category 的链接从输入节点指向的所有节点。 |
提示
通常,对于一组给定的输入节点存在一个“默认”操作,此操作由体系结构资源管理器自动选定。 若要获取相同的行为,请使用空操作://
由于空白在 DGQL 中没有意义,因此必要时您可以设置查询的格式以适合某个行。 在使用带有 GraphCmd 的 –exec 选项时,这将很有用。
在调试 DGQL 时,使用体系结构资源管理器中的操作“Execute Expanded"”可帮助您查看查询的每个步骤,并查找未产生预期结果的步骤。
示例
下面的 DGQL 语句执行一条查询,如下列步骤中所述:
+ Id.Equals("Microsoft.Solution.ClassView") / "Microsoft.Solution.ClassView" / * / "Node:Both:CodeSchema_Class" / + CodeSchemaProperty_IsPublic.Equals("True")
首先,选择体系结构资源管理器的第一列中的**“类视图”**节点。
执行操作“Microsoft.Solution.ClassView"”,这将返回解决方案中的所有命名空间。
使用 * 选择所有命名空间。
通过指向任一方向的链接选择具有 CodeSchema_Class 类别且与这些命名空间相关的所有节点。 它们通常是包容链接。
仅从生成的类中筛选出具有属性 CodeSchemaProperty_IsPublic="True" 的类。
从技术上说,"Microsoft.Solution.ClassView" 操作不是必需的操作,因为它是**“类视图”**节点的“默认”操作。 因此,可以将此操作替换为 // 以简化查询,并在单个行上设置其格式,如下所示:
+Id.Equals("Microsoft.Solution.ClassView")//*/"Node:Both:CodeSchema_Class"/+CodeSchemaProperty_IsPublic.Equals("True")