在运行时使用 nuget 引用编译解决方案

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

我目前正在尝试在我自己的程序的运行时执行期间编译解决方案。这个解决方案是用户定义的,必须支持任意数量的项目,并且在这些项目中用户想要添加的任何 nuget 依赖项。例如,具有如下定义的单个 C# 项目的解决方案:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
    <PackageReference Include="xunit" Version="2.4.1" />
  </ItemGroup>
</Project>

如果用户决定在他们的代码中使用 xunit 或 Newtonsoft.Json 类,则应该编译。

我目前正在按照以下步骤编译项目:

using var workspace = MSBuildWorkspace.Create();
var solution = await workspace.OpenSolutionAsync(solutionPath, cancellationToken: token);
foreach (var project in solution.Projects)
{
    var compilation = await project.GetCompilationAsync(token);
    // handle compilation
}

我面临的问题是 MSBuild 似乎没有解析所有 nuget 引用。这很奇怪,因为可以使用

Newtonsoft.Json
,并且使用提示路径添加对 dll 的引用也可以。但是,
xunit
永远不会被解析,编译失败并显示找不到命名空间
Xunit
的消息。
compilation.References
只显示系统引用以及出于某种原因总是 Newtonsoft.Json,即使它没有被引用。
workspace.Diagnostics
是空的,我很茫然

如何让 MSBuild 包含我的用户将引用的 nuget 包?

c# roslyn
1个回答
0
投票

问题是当您调用

GetCompilationAsync
时,Roslyn 不会恢复您的项目。不幸的是,没有简单的方法可以使用 MSBuildWorkspace API 恢复您的项目。幸运的是,
Microsoft.Build
NuGet 包就是答案。

确保从您首先使用

Microsoft.Build.*
dll 中定义的类的不同函数调用 MSBuildLocator,否则您将获得 FileNotFoundException,因为尚无法为您的程序找到 DLL。之后,我使用了
SolutionFile.Parse
,遍历了那里的每个项目,并使用了来自 Roslyn this 类的“深受启发”的代码,以便以
Restore
的目标步骤调用 MSBuild。这样做之后,我创建了我的 MSBuildWorkspace,打开了解决方案,现在每次更新项目的依赖项时编译都会成功。

如果有人知道更简单的方法,请告诉我

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