使用依赖项关系图验证代码

为何使用依赖项关系图?

若要确保代码与其设计不冲突,请在 Visual Studio 中使用依赖项关系图验证代码。 这可以帮助你:

  • 查找代码中的依赖项与依赖项关系图上的依赖关系之间的冲突。

  • 查找可能受建议更改影响的依赖项。

    例如,可以编辑依赖项关系图以显示潜在的体系结构更改,然后验证代码以查看受影响的依赖项。

  • 重构或将代码迁移到其他设计。

    查找将代码移动到其他体系结构时需要工作的代码或依赖项。

要求

  • Visual Studio

    若要为 .NET Core 项目创建依赖项关系图,必须具有 Visual Studio 2019 版本 16.2 或更高版本。

  • 具有依赖关系图的建模项目的解决方案。 此依赖项关系图必须链接到要验证的 C# 或 Visual Basic 项目中的项目。 请参阅 从代码创建依赖项关系图

若要查看 Visual Studio 哪些版本支持此功能,请参阅 版本对体系结构和建模工具的支持

可以从 Visual Studio 中的打开依赖项关系图或命令提示符手动验证代码。 还可以在运行本地生成或 Azure Pipelines 生成时自动验证代码。

重要

如果要使用 Team Foundation Server (TFS)运行层验证,还必须在生成服务器上安装相同版本的 Visual Studio。

实时依赖项验证

依赖项验证实时发生,错误会立即显示在 错误列表中

  • C# 和 Visual Basic 支持实时验证。

  • 若要在使用实时依赖项验证时启用完整解决方案分析,请从显示在错误列表中的黄色提示栏打开选项设置。

    • 如果您不感兴趣查看在您的解决方案中所有的体系结构问题,可以选择永久关闭该提示栏。
    • 如果未启用完整的解决方案分析,则仅对正在编辑的文件执行分析。
  • 升级项目以启用实时验证时,对话框会显示转换进度。

  • 更新项目进行实时依赖项验证时,NuGet 包的版本会升级为所有项目的相同版本,并且是正在使用的最高版本。

  • 添加新的依赖项验证项目将触发项目更新。

查看项目是否支持验证

可以将图层链接到网站、Office 文档、纯文本文件以及包含在跨多个应用共享项目中的文件,但这些链接项不会包含在验证过程中。 当这些层之间没有依赖项时,引用链接到单独层的项目或程序集不会显示验证错误。 除非代码使用这些引用,否则此类引用不被视为依赖项。

  1. 在依赖项关系图上,选择一个或多个层,右键单击所选内容,然后单击“ 查看链接”。

  2. 层资源管理器中,查看 “支持验证 ”列。 如果值为 false,则该项不支持验证。

包括其他用于验证的 .NET 程序集和项目

将项拖到依赖项关系图时,对相应的 .NET 程序集或项目的引用会自动添加到建模项目中的 “层引用 ”文件夹中。 此文件夹包含对验证期间分析的程序集和项目的引用。 可以包括其他 .NET 程序集和项目进行验证,而无需手动将其拖动到依赖项关系图。

  1. 解决方案资源管理器中,右键单击建模项目或 层引用 文件夹,然后单击“ 添加引用”。

  2. “添加引用 ”对话框中,选择程序集或项目,然后单击“ 确定”。

手动验证代码

如果你有一个链接到解决方案项的开放依赖项关系图,则可以从关系图中运行 “验证 ”快捷方式命令。 还可以使用命令提示符运行 msbuild 命令,并将 /p:ValidateArchitecture 自定义属性设置为 True。 例如,在代码中进行更改时,请定期执行层验证,以便尽早捕获依赖项冲突。

从打开的依赖项关系图验证代码

  1. 右键单击关系图面,然后单击“ 验证体系结构”。

    注释

    默认情况下,依赖关系图(.layerdiagram)文件中的 生成操作 属性会设置为 验证,以便在验证过程中包含该关系图。

    错误列表 ”窗口报告发生的任何错误。 有关验证错误的详细信息,请参阅 解决层验证问题

  2. 若要查看每个错误的源,请在 “错误列表 ”窗口中双击该错误。

    注释

    Visual Studio 可能会显示代码图,而不是错误的来源。 如果代码依赖于依赖项关系图未指定的程序集,或者代码缺少依赖项关系图指定的依赖项,则会出现这种情况。 查看代码映射或代码以确定依赖项是否应存在。 有关代码图的详细信息,请参阅 跨解决方案映射依赖项

  3. 若要管理错误,请参阅 “解决层验证错误”。

在命令提示符处验证代码

  1. 打开 Visual Studio 命令提示符。

  2. 选择下列选项之一:

    • 若要针对解决方案中的特定建模项目验证代码,请使用以下自定义属性运行 MSBuild。

      msbuild <FilePath+ModelProjectFileName>.modelproj /p:ValidateArchitecture=true
      

      -或-

      浏览到包含建模项目(.modelproj)文件和依赖项关系图的文件夹,然后使用以下自定义属性运行 MSBuild:

      msbuild /p:ValidateArchitecture=true
      
    • 若要针对解决方案中的所有建模项目验证代码,请使用以下自定义属性运行 MSBuild:

      msbuild <FilePath+SolutionName>.sln /p:ValidateArchitecture=true
      

      -或-

      浏览到解决方案文件夹,该文件夹必须包含包含依赖项关系图的建模项目,然后使用以下自定义属性运行 MSBuild:

      msbuild /p:ValidateArchitecture=true
      

      将列出发生的任何错误。 有关 MSBuild 的详细信息,请参阅 MSBuildMSBuild 任务

    有关验证错误的详细信息,请参阅 解决层验证问题

管理验证错误

在开发过程中,你可能希望在验证期间抑制某些报告的冲突。 例如,你可能想要抑制已处理或与你的具体情境无关的错误。 在忽略一个错误时,最好在 Team Foundation 中记录一个工作项。

警告

必须已连接到 TFS 源代码控制(SCC),才能创建或链接到工作项。 如果尝试打开与其他 TFS SCC 的连接,Visual Studio 会自动关闭当前解决方案。 在尝试创建或链接到工作项之前,请确保已连接到相应的 SCC。 在 Visual Studio 的更高版本中,如果未连接到 SCC,菜单命令将不可用。

为验证错误创建工作项

  • 在“ 错误列表 ”窗口中,右键单击错误,指向 “创建工作项”,然后单击要创建的工作项的类型。

使用这些任务在 “错误列表” 窗口中管理验证错误:

需要遵循的步骤
在验证期间禁止显示所选错误 右键单击一个或多个选定的错误,指向 “管理验证错误”,然后单击“ 禁止显示错误”。

被抑制的错误采用删除线格式。 下次运行验证时,不会显示这些错误。

抑制错误在相应依赖项关系图文件的 .suppresss 文件中进行跟踪。
停止禁止显示所选错误 右键单击所选禁止显示的错误或错误,指向 “管理验证错误”,然后单击“ 停止禁止显示错误”。

下次运行验证时,将显示已抑制的选定错误。
“错误列表” 窗口中还原所有禁止显示的错误 右键单击 “错误列表 ”窗口中的任意位置,指向 “管理验证错误”,然后单击“ 显示所有禁止显示的错误”。
“错误列表” 窗口中隐藏所有禁止显示的错误 右键单击 “错误列表 ”窗口中的任意位置,指向 “管理验证错误”,然后单击“ 隐藏所有禁止显示的错误”。

自动验证代码

每次运行本地生成时,都可以执行层验证。 如果您的团队使用 Azure DevOps,则可以通过受控签入来执行层验证,您可以创建自定义 MSBuild 任务来实现这一点,并使用生成的报告收集验证错误。 若要创建封闭式签入版本,请参阅 TFVC 封闭签入

在本地生成期间自动验证代码

使用文本编辑器打开建模项目 (.modelproj) 文件,然后包括以下属性:

<ValidateArchitecture>true</ValidateArchitecture>

- 或 -

  1. 解决方案资源管理器中,右键单击包含依赖项关系图或关系图的建模项目,然后单击“ 属性”。

  2. “属性” 窗口中,将建模项目的 “验证体系结构 ”属性设置为 True

    这包括验证过程中的建模项目。

  3. 解决方案资源管理器中,单击要用于验证的依赖项关系图(.layerdiagram)文件。

  4. “属性” 窗口中,确保关系图的 “生成操作” 属性设置为 “验证”

    这包括验证过程中的依赖项关系图。

若要在“错误列表”窗口中管理错误,请参阅 “解决层验证错误”。

排查层验证故障

下表描述了层验证问题及其解决方法。 这些问题不同于代码与设计之间的冲突导致的错误。 有关这些错误的详细信息,请参阅 排查层验证问题

问题 可能的原因 解决方案
验证错误不会按预期发生。 验证不适用于从解决方案资源管理器中其他依赖项关系图复制且处于同一建模项目中的依赖项关系图。 以这种方式复制的依赖项关系图包含与原始依赖项关系图相同的引用。 向建模项目添加新的依赖项关系图。

将源依赖项关系图中的元素复制到新关系图。

解决层验证错误

针对依赖项关系图验证代码时,当代码与设计冲突时,会发生验证错误。 例如,以下条件可能会导致验证错误发生:

  • 工件被分配到不正确的层。 在这种情况下,移动工件。

  • 一个构件(例如类)以与架构相冲突的方式使用另一个类。 在这种情况下,重构代码以删除依赖项。

若要解决这些错误,请更新代码,直到验证期间不再出现错误。 可以迭代方式执行此任务。

以下部分介绍这些错误中使用的语法,解释这些错误的含义,并建议可以执行哪些作来解决或管理这些错误。

语法 说明
ArtifactNArtifactTypeN ArtifactN 是一个与依赖关系图中的某一层相关联的工件。

ArtifactTypeNArtifactN 的类型,例如 方法, 例如:

MySolution.MyProject.MyClass.MyMethod(Method)
NamespaceNameN 命名空间的名称。
LayerNameN 依赖项关系图上层的名称。
DependencyType Artifact1Artifact2 之间的依赖关系类型。 例如,Artifact1Artifact2 之间有调用关系。
错误语法 错误说明
DV0001: 依赖项无效 当映射到层的代码元素(命名空间、类型、成员)引用映射到另一层的代码元素时,将报告此问题,但在包含此层的依赖项验证关系图中,这些层之间没有依赖关系箭头。 这是依赖项约束冲突。
DV1001: 命名空间名称无效 在代码元素所属的层上报告了此问题,该层的“允许的命名空间名称”属性未包含定义该代码元素的命名空间。 这是命名约束违规。 请注意,“被允许的命名空间名称”的语法是一个以分号分隔的命名空间列表,其中允许定义与层相关联的代码元素。
DV1002: 依赖于不可推断的命名空间 在与层关联的代码元素上存在一个问题,此元素引用了在层的“无法引用的命名空间”属性中定义的命名空间中定义的另一个代码元素。 这是命名约束冲突。 请注意,“不可推断命名空间”属性定义为不应在此层关联的代码元素中引用的分号分隔的命名空间列表。
DV1003: 不允许的命名空间名称 此问题报告在与某层相关的代码元素上,该层的“不允许的命名空间名称”属性包含定义此代码元素的命名空间。 这是命名约束违规。 请注意,“不允许的命名空间名称”属性定义为一个分号分隔的命名空间列表,在该列表中不应定义与此层关联的代码元素。
DV2001: 层关系图状态 此问题报告在不包含依赖项关系图文件但引用依赖项验证分析器的项目上。 如果未使用依赖项验证,可以直接从解决方案资源管理器中删除“Microsoft.DependencyValidation.Analyzers”或取消此警告。 若要添加依赖项关系图,请参阅 从代码创建依赖项关系图
DV2002: 未映射的类型基 当代码元素未映射到任何层时,将报告此问题。
DV3001: 缺少链接 层“LayerName”链接到无法找到的“Artifact”。 是否缺少程序集引用?
DV9001: 体系结构分析发现内部错误 结果可能不完整。 有关详细信息,请参阅详细的生成事件日志或输出窗口。