将项目参考更改为构建时的NuGet软件包参考

时间:2019-02-25 17:08:11

标签: .net azure-devops nuget azure-pipelines

我有一个带有两个项目的Visual Studio解决方案-一个包含一些逻辑的.NET标准(2.0)库和一个包含用户界面等的.NET Framework(4.6.1)类库。然后,.NET Framework库具有。 NET标准库已添加为项目参考,因此它可以使用逻辑库中包含的方法。

然后,我在Azure DevOps中使用Azure Pipelines来构建这两个项目,将它们打包为NuGet程序包,然后将其推送到Azure Devops(Azure Artifacts)提供的NuGet服务器。

但是,发布NuGet程序包时,它们仅包含在NuGet中对我已通过NuGet添加到项目中的程序包的依赖项。我理想的情况是将.NET标准(逻辑)库打包并推送到NuGet服务器时,将对NuGet的引用(具有更新的版本号等)添加到我的.NET Framework(UI)库中。

有没有其他人遇到这个问题,请给我一些有关如何解决它的指导?我在网上看过一眼,至今为止还是空白。

谢谢!

5 个答案:

答案 0 :(得分:1)

我的回答分为两部分。

首先,如果您使用的是dotnet packmsbuild -t:pack,而没有nuspec文件,则项目引用会自动成为nuget依赖项。我使用以下命令对此进行了验证:

dotnet new classlib -n ProjectA
dotnet new classlib -n ProjectB
dotnet add ProjectB/ProjectB.csproj reference ProjectA/ProjectA.csproj
dotnet pack ProjectB/ProjectB.csproj

ProjectB.1.0.0.nupkgProjectA v1.0.0有一点依赖。这对于SDK样式的项目可以“开箱即用”,但是,如果您有一个“旧样式”项目(导入Microsoft.CSharp.targets),则需要添加对NuGet.Build.Tasks.Pack的程序包引用。如果使用PackageReference,则可能需要编辑csproj并设置此依赖项以将PrivateAssets设置为all,以避免此程序包成为nuget依赖项。我不知道如果您正在使用packages.config,或者甚至可以做到的话。如果您使用的是msbuild或dotnet pack,但您也有自己的nuspec文件,建议不要使用它。您可以通过在csproj中设置正确的属性或项属性来进行nuspec中的任何操作,并使包目标自动生成nuspec。当您拥有自己的nuspec时,nuget自动生成的部分功能会关闭,因此您可能会变得更难为自己。

我在旧式csproj文件中对nuget pack的记忆是,只要引用的项目在与{{相同的目录中有一个<project name>.nuspec文件,nuget就会自动使项目引用nuget依赖项。 1}}文件(我几乎可以肯定它已经记录在docs.microsoft.com/nuget上的某个位置)。但是,如果您的从属项目是SDK样式的项目(例如.NET Core或.NET Standard项目需要),那么我已经建议不要在这些项目中使用nuspec文件,因此您应该真正考虑使用pack目标并停止使用<project name>.csproj

我的答案的第二部分将直接回答您的问题,这是关于如何使项目引用某些构建中的程序包引用。首先,您需要通过使用SDK样式项目或通过引用NuGet.Build.Tasks.Pack包来使用包目标。这样,您就不会使用nuget pack文件,并且所有内容都在nuspec中定义,而csproj只是一个MSBuild文件。 MSBuild具有条件,因此请手动编辑csproj并使项目引用具有特定条件,并使程序包引用具有相反的条件。我建议使用$(CI)之类的变量,以便您可以使用msbuild -t:pack -p:CI=true测试该包,并且在CI机器上,只需将CI作为环境变量设置为true即可。由于NuGet已经内置了将项目引用转换为nuget依赖项的内置功能,因此我建议使用该功能,而不是在程序包引用和项目引用之间进行切换,因此,我将不提供有关如何执行此操作的复制粘贴示例。但是,如果不是XY-problem的情况,而您确实需要这样做,那么我已经给了足够的指导,让您能够弄清楚其余的事情。

答案 1 :(得分:0)

当不使用.nuspec文件时,NuGet CLI的依赖项for PackageReferences和项目引用(仅当项目也是.net Core或.net Standard吗?)也会出现问题。

使用dotnet packmsbuild -t:pack将项目引用包含为nuget依赖项。这也解决了PackageReferences未被写为依赖项的问题。

假设您的.net Framework项目是Visual Studio的现成产品,则需要引用 Nuget.Build.Tasks.Pack nuget包来访问必要的目标。在还原任何nuget之前,我们会将这些数据写入具有构建服务器的.shell的.csproj文件中,以便进行任何nuget还原,因此对于新的完整框架项目(我们正努力摆脱创建过程),不会忘记这一点。正如@zivkan所提到的,您可能想要

  

将PrivateAssets设置为all,以避免此程序包成为nuget依赖项

<PackageReference Include="NuGet.Build.Tasks.Pack">
  <PrivateAssets>all</PrivateAssets>
  <Version>4.8.0</Version>
</PackageReference>

答案 2 :(得分:0)

  

将项目引用更改为构建时的NuGet包引用

恐怕您在构建期间无法将项目引用转换为nuget包引用。那是因为它们是引用的两种不同处理方式。尽管现在有一些扩展可以将项目引用转换为nuget包引用,但是它们需要手动操作,我们无法在构建期间使用它。

检查another thread了解更多详细信息。

因此,我们无法将项目引用.NET Standard (2.0) library更改为NuGet程序包引用,并添加到 build 上的.NET Framework(UI)库中。

个人而言,要解决此问题,可以将.net Standard(.netSrd)项目引用用作本地的nuget包引用,当您更新.net Standard项目的版本号nuget包时,可以更新此包在您的Azure Artifacts中,并在创建.NET Framework(UI)库时使用自定义nuget task命令调用nuget update命令将软件包更新为最新版本。

从以下位置查看详细信息:

Update NuGet package to last version after build in VSTS

希望这会有所帮助。

答案 3 :(得分:0)

如果您正在使用新的csproj格式(专为.NET Core设计,但可以与任何.NET一起使用),则它非常简单。

在要作为NuGet软件包发布的项目中,必须在csproj中添加以下内容:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

除此之外,您仅需使用ProjectReferences引用其他项目。 MSBuild将构建所有内容,并且在发布NuGet程序包时,会将ProjectReferences更改为PackageReferences。

答案 4 :(得分:0)

  

如果您有一个ProjectReference,它将覆盖任何包   在还原图中引用相同的程序包ID。

来源:Resolve package references to projects (dotnet github issue)

我自己尝试过(在csproj文件中添加了ProjectReference和PackageReference)。它成功构建,并且输出的NuGet文件包含对另一个NuGet包的依赖关系。