【问题标题】:How to determine which of a project's package references are not needed?如何确定不需要项目的哪些包引用?
【发布时间】:2021-09-08 18:16:25
【问题描述】:

我有一个项目解决方案,可以构建。 这些项目大多是旧样式(XML 格式)*.csproj,而不是较新的 SDK 样式,并且项目引用了 NuGet 包。

我相信一些包引用是不需要的或者已经过时了,例如:

  • 包引用在*.csproj和/或packages.config中定义
  • 但不需要包引用,即项目的源代码不使用包,如果包被删除,项目仍然会构建

转换为 SDK 风格的项目格式时会出现问题——因为 packages.config(由 VS IDE 创建)包含项目的依赖项和子依赖项,而是一个新的 SDK 风格的项目只需要定义它的依赖(而不是它的子依赖)。

如何找到不需要的包引用?

请假设:

  • 我可以解析*.csproj 和/或packages.config,因此我知道所有包引用的列表——我不知道需要哪些引用
  • 我只对项目直接依赖的包感兴趣,即我不想要在运行时需要但在构建时不需要的包,因为它们是依赖项的依赖项。李>

我不想实验——即“依次删除每个包引用,并尝试重新构建项目,看看在构建时是否需要引用”——太耗时了。

我能想到的唯一算法是:

  1. 使用反射打开引用的包并获取定义的类型或命名空间列表
  2. 查看是否在项目中使用——通过在源代码中搜索命名空间字符串

您能否提出一个更好的方法——更准确的方法,或者使用现有的工具?

【问题讨论】:

  • 转换项目后,您可以执行dotnet restore 生成obj/project.assets.json,其中包含所有依赖项的图形(以JSON 格式)。然后,您可以使用它来确定哪些是顶级依赖项。这并不完全正确,因为您将剪切对包的任何引用,这些引用既是直接引用又是传递引用,并且您不会剪切对完全未使用的包的引用
  • Visual Studio 16.10 具有“删除未使用的引用”功能,请参阅 changelog。它应该比任何手写解决方案都好
  • @JL0PD 谢谢,如果是答案,我可以投票。所以——我认为如果是旧式的非 SDK 项目格式(例如使用 packages.config),则必须显式引用子依赖项(即依赖项的依赖项),如果是 SDK,则不需要引用-style *.csproj——不是这样吗?您是否碰巧知道“删除未使用的引用”功能支持这些场景中的哪一个,或者两者都支持,即它根据 *.csproj 的格式正确变化?
  • 奇怪的是,rationale for that,即它减少了应用程序启动时间,似乎与 in my answer below 的观察结果相矛盾,in my answer below 表示未使用的引用不在元数据中。
  • @ChrisW,我认为它只适用于 SDK 风格的项目,而不是旧项目。目前没有人应该使用旧格式,除非你需要使用 COM(如果我没记错的话)

标签: .net msbuild nuget


【解决方案1】:

从 Visual Studio 2019 16.10 开始,feature 称为“删除未使用的引用”,用于从项目文件中删除对其他项目和 nuget 包的引用。目前它处于预览状态,您需要启用它:转到Tools > Options > Text Editor > C# > Advanced 并选择Show “remove Unused References” command in Solution Explorer (experimental)

之后,您将能够从项目中删除引用

我相信他们会把它移到功能的其他地方,因为它不仅适用于 C#,而且适用于一般的 dotnet

【讨论】:

    【解决方案2】:

    显然,如果一个包被引用但未使用,那么它不会出现在构建的程序集的清单中。

    所以我认为这个检查会起作用,假设可以构建程序集(即它的清单存在)。

    可能存在一种极端情况,即在运行时需要引用的实现但不在清单中——如果实现是动态加载的;但动态加载并不常见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多