【问题标题】:Treat ProjectReference as PackageReference or allow PackageReference to local csproj将 ProjectReference 视为 PackageReference 或允许 PackageReference 到本地 csproj
【发布时间】:2018-10-23 14:51:06
【问题描述】:

我有一个 netstandard2.0 csproj(我们称之为 MyPackage),它在构建时(由 GeneratePackageOnBuild 指定)打包到一个 nuget 包中。这个 nuget 包在构建目录中有自定义的 props 和目标(因此引用项目会导入这些)。

我在同一个解决方案中还有另一个项目(我们称之为 MyConsumer)用于测试 MyPackage。我希望 MyConsumer 在构建时从 MyPackage 导入构建资产道具和目标,就像它作为来自某个远程 nuget 源的 PackageReference 一样使用它。

我怎样才能让这个工作(最简单)?

我已经能够通过一个非常复杂的方法来做到这一点,我让 MyConsumer 将 PackageReference 添加到 MyPackage 并覆盖 MyConsumer 中的 RestoreSources 以指向 MyPackage 的 bin 目录。当运行 dotnet build 或 Visual Studio build 的 sln 时,这会变得非常奇怪,因为项目元数据是在还原期间为所有项目预先生成的,因此此时 MyPackage 不存在。解决方案是在 MyConsumer 项目中添加对 MSBuild 的嵌套调用,但这变得更糟,因为 Visual Studio 恢复的操作与 dotnet build 执行的自动恢复完全不同。

有什么简单的方法吗?

这就是我现在拥有的

<Project> 
  <Target Name="Build">    
    <Message Text="Running inner build" Importance="high" />

    <!-- 
    Need to call MSBuild twice, once to restore, then again to restore and build to get the restore of the Sdk to work
    because of this bug in MSBuild: https://github.com/Microsoft/msbuild/issues/2455
    Note the trailing Prop=1 is required to get MSBuild to invalid it's cache of the project target imports
    -->
    <MSBuild Projects="$(MSBuildProjectFullPath)" Targets="Restore" Properties="Configuration=$(Configuration);Version=$(Version);IsInnerBuild=true;Prop=1" />
    <!-- Have to use dotnet build instead of another call to MSBuild because of another bug that prevents proper imports within the same physical process  -->
    <Exec Command="dotnet build /p:Configuration=$(Configuration) /p:Version=$(Version) /p:IsInnerBuild=true" />
    <Message Text="Finished inner build" Importance="high" />
  </Target>

  <Target Name="Restore" />

  <Target Name="RemoveBin">
    <RemoveDir Directories="bin" />
  </Target>

  <!-- Don't do real cleans old rebuild since it breaks MSBuild due to the same above bug -->
  <Target Name="Rebuild" DependsOnTargets="RemoveBin;Build">
  </Target>
</Project>

【问题讨论】:

    标签: msbuild visual-studio-2017 .net-core nuget msbuild-15


    【解决方案1】:

    将 ProjectReference 视为 PackageReference 或允许 PackageReference 到本地 csproj

    如果我理解正确,您希望生成带有项目MyPackage 的包,然后将其安装到测试项目MyConsumer 并在构建时从 MyPackage 导入构建资产道具和目标。

    要实现这个目标,你需要完成以下几件事:

    • 确保项目 MyPackage 在项目 MyConsumer 之前构建。
    • 将包设置到打包器源中
    • 在构建期间将包 MyPackage.nupkg 添加到测试项目 MyConsumer

    以上详情:

    • 确保项目 MyPackage 在项目 MyConsumer 之前构建。

    由于您要测试由项目MyConsumer生成的包,所以在测试项目使用它之前,您应该确保该包已运行,所以我们需要设置项目MyConsumer引用项目@987654332 @。

    • 将包设置到打包器源中

    您可以使用项目MyPackage 的构建后事件将包MyPackage.nupkg 复制到本地提要,或者您可以将MyPackage.nupkg 的bin 目录添加到包源中。

    • 在构建期间将包 MyPackage.nupkg 添加到测试项目 MyConsumer

    使用 VS 2017 和测试项目MyConsumerPackageReference 样式,您可以将Directory.Build.props 文件设置到包含您需要的测试项目MyConsumer 的解决方案的根目录中:

    <Project>
      <ItemGroup>
        <PackageReference Include="MyPackage" Version="1.0.* />
      </ItemGroup>
    </Project>
    

    这会将这些 NuGet 包添加到解决方案中的测试项目MyConsumer,它将用作来自某个远程 nuget 源的 PackageReference。

    查看Martin`s answer 了解更多详情。

    希望这会有所帮助。

    【讨论】:

    • 这很棒 - 但正是我正在做的事情。这种方法的问题是关于还原包和解决包特定构建目标的 MSBuild“问题/错误/您想调用的任何内容”。请参阅上面的答案问题,了解实现此工作所需的所有复杂性......
    • @Jeff,是的,你是对的。如果您使用 dotnet 构建解决方案,您将遇到问题“在还原期间为所有项目预先生成项目元数据,因此此时 MyPackage 不存在。”。要解决此问题,您可以先使用 MSBuild 构建项目 MyPackage,然后使用 msbuild /t:restore 恢复解决方案的包。此刻,我们似乎没有任何简单的解决方案。
    • 谢谢利奥。 MSBuild 15 和 nuget 集成的增强功能非常棒,但是没有测试和开发的方法,我们只能得到有缺陷的、不成熟的解决方案。我会坚持使用复杂的方法。请注意,它并不像构建/恢复那么简单,即使因为 MSBuild 如何进行缓存存在各种错误(请参阅我上面发布的代码示例中的 cmets)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    相关资源
    最近更新 更多