在Roslyn中是否有一种方法或途径来列举一个给定的C#项目在编译时使用的所有汇编。

问题描述 投票:0回答:1

我正在开发一个应用程序,它可以检测并消除给定C#项目中的无用外部引用,例如一个被引用但未使用的包。为此,我需要枚举所有在编译和运行时使用的程序集。对于那些在运行时使用的程序集,我可以使用反射来获取名称,特别是调用 Assembly.GetReferencedAssemblies(). 但对于那些只在编译时使用的,我认为没有办法在不使用Roslyn的情况下列出它们。请你回答我的问题。

c# assemblies roslyn roslyn-code-analysis external-assemblies
1个回答
0
投票

这只是一个简单的方法,远非完美。我相信你可以更深入地了解Roslyn,并根据自己的需要尽情地玩耍。我也相信在编译器和Roslyn方面有比我更优秀的专家 :)

请注意,这种方法不能处理动态加载的程序集。它可以避免运行项目。

引用的程序集

您可以使用XML解析器代替Roslyn来分析项目或解决方案文件。在那里你会发现所有被引用的包和项目的列表,例如:.NET Core 3.1。

  <ItemGroup>
    <ProjectReference Include="..\Common\Common.csproj" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="MessagePack" Version="2.1.115" />
  </ItemGroup>

上面的例子来自于一个.NET Core 3.1项目文件。

更新

为了收集 转属关系 也有几种选择。

  • 对于.NET Core项目,您可以调用 dotnet restore 然后读取以下文件 $ProjectFolder/obj/project.assets.json. 它是一个json文件,包含所有被解析的引用,包含NuGet和运行时包。

  • 如果你想避免恢复projectsolution,你可以从在 .csproj 如上所述,并使用 NuGet服务器API 来获取每个依赖关系的数组。递归地这样做会得到与 dotnet restore. NuGet核心 将API包装成C#类,所以你可以直接从你的代码中调用它。依赖关系可以像这里一样轻松查询。如何从私有的NuGet feed中获取NuGet包的依赖关系?

所需的程序集

现在你需要确定那些真正需要的东西。编译过程会处理这些问题。它不会(据我所知)在编译后的代码中插入任何不必要的引用。

Roslyn语义模型

在这个问题中解决了。Roslyn获取类的依赖关系

IL选项

您可以使用Roslyn编译给定的项目,然后加载生成的IL,并查找引用,如 [System.Private.CoreLib]. 只需将所有引用的装配体扔进一个 HashSet 并在IL中找到匹配的调用后删除它们。由此产生的集合将包含可以被删除的引用。

也许 本项目 可以帮助查看IL。同时 夏普实验室 当您需要Roslyn输出示例时,可以非常方便地使用。

加载选项

如果你对加载编译后的项目没有意见,你可以使用 Assembly.GetReferencedAssemblies() 如你在问题中指出的,而不是分析IL。

© www.soinside.com 2019 - 2024. All rights reserved.