Roslyn中是否有方法或方法枚举给定C#项目在编译时使用的所有程序集 更新罗斯林语义模型 IL选项加载选项

我正在开发一个应用程序,该程序可以检测并消除给定C#项目中无用的外部引用,例如引用但未使用的包。为此,我需要枚举在编译和运行时使用的所有程序集。对于在运行时使用的变量,我可以使用反射专门调用Assembly.GetReferencedAssemblies()来获得名称。但是对于仅在编译时使用的那些,我认为如果不使用Roslyn,就无法列出它们。您能不能解决我遇到的问题?

iCMS 回答:Roslyn中是否有方法或方法枚举给定C#项目在编译时使用的所有程序集 更新罗斯林语义模型 IL选项加载选项

这只是一种简单的方法,远非完美。我相信您可以根据自己的需要去加深与Roslyn的交流。我也肯定有比我更好的编译器和Roslyn专家:)

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

引用程序集

您可以使用XML解析器代替Roslyn来分析项目或解决方案文件。在那里,您会找到所有引用的软件包和项目的列表,例如:

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

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

上面的示例来自.NET Core 3.1项目文件。

更新

为了收集transitive dependencies,还有几种选择。

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

  • 如果要避免恢复项目/解决方案,可以如上所述从.csproj中找到的程序包开始,然后使用NuGet Server API获取每个程序包的依赖项数组。递归执行此操作将产生与dotnet restore相同的结果。 NuGet Core将API包装为C#类,因此您可以直接从代码中调用它。依赖关系可以像下面这样轻松查询:How to get the dependencies of a NuGet package from private NuGet feed?

所需的程序集

现在,您需要确定真正必要的那些。编译过程会解决这个问题。据我所知,它不会在编译后的代码中插入任何不必要的引用。

罗斯林语义模型

此问题的解决地址:Roslyn getting dependencies for class

IL选项

您可以使用Roslyn编译给定的项目,然后加载生成的IL并查找诸如[System.Private.CoreLib]之类的引用。只需将所有引用的程序集放入HashSet中,然后在IL中找到匹配的调用,即可将其删除。结果集将包含可以删除的引用。

也许this project可以帮助查看IL。另外,当您需要罗斯林输出示例时,SharpLab也非常方便。

加载选项

如果可以很好地加载已编译的项目,则可以按照问题中的说明使用Assembly.GetReferencedAssemblies()而不用分析IL。

本文链接:https://www.f2er.com/2291457.html

大家都在问