简体   繁体   English

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

[英]Changing a project reference to a NuGet package reference on build

I have a Visual Studio solution with two projects - a .NET Standard (2.0) library containing some logic and a .NET Framework (4.6.1) class library containing user interface etc. The .NET Framework library then has the .NET Standard library added as a project reference so it can use methods contained in the logic library.我有一个包含两个项目的 Visual Studio 解决方案 - 一个包含一些逻辑的 .NET Standard (2.0) 库和一个包含用户界面等的 .NET Framework (4.6.1) 类库。 .NET Framework 库然后有 .NET Standard 库添加为项目参考,以便它可以使用逻辑库中包含的方法。

I am then using Azure Pipelines in Azure DevOps to build these two projects, pack them as NuGet packages and push them to a NuGet server provided by Azure Devops (Azure Artifacts).然后我在 Azure DevOps 中使用 Azure Pipelines 来构建这两个项目,将它们打包为 NuGet 包并将它们推送到 Azure DevOps(Azure Artifacts)提供的 NuGet 服务器。

However, when the NuGet packages are published, they only include dependencies in NuGet on packages that I've added to the projects via NuGet.但是,发布 NuGet 包时,它们仅包含 NuGet 中对我通过 NuGet 添加到项目的包的依赖项。 What I want ideally is when my .NET Standard (logic) library is packaged up and pushed to the NuGet server, a reference to it on NuGet (with the updated version number etc) is added to my .NET Framework (UI) library.理想情况下,我想要的是当我的 .NET Standard(逻辑)库打包并推送到 NuGet 服务器时,NuGet 上对它的引用(带有更新的版本号等)被添加到我的 .NET Framework (UI) 库中。

Has anyone else had this issue that can give me some guidance on how to solve it please?有没有其他人遇到过这个问题,可以给我一些有关如何解决它的指导吗? I've had a look online and drawn a blank so far.到目前为止,我已经在网上查看并绘制了一张空白。

Thanks!谢谢!

There are two parts to my answer.我的回答有两个部分。

Firstly, if you're using dotnet pack or msbuild -t:pack , without a nuspec file, then project references automatically become nuget dependencies.首先,如果您使用dotnet packmsbuild -t:pack ,而没有 nuspec 文件,则项目引用会自动成为 nuget 依赖项。 I verified this using the following commands:我使用以下命令验证了这一点:

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.nupkg has a nuget dependency on ProjectA v1.0.0 . ProjectB.1.0.0.nupkgProjectA v1.0.0有 nuget 依赖。 This works "out of the box" with SDK style projects, but if you have an "old style" project (that imports Microsoft.CSharp.targets), you'll need to add a package reference to NuGet.Build.Tasks.Pack.这适用于 SDK 样式项目“开箱即用”,但如果您有一个“旧样式”项目(导入 Microsoft.CSharp.targets),则需要添加对 NuGet.Build.Tasks.Pack 的包引用. If you use PackageReference, you may need to edit your csproj and set this dependency to set PrivateAssets to all to avoid this package becoming a nuget dependency.如果您使用 PackageReference,您可能需要编辑您的 csproj 并设置此依赖项以将 PrivateAssets 设置为 all 以避免此包成为 nuget 依赖项。 I don't know what the equivalent is if you're using packages.config, or if it's even possible.如果您使用的是packages.config,或者甚至可能的话,我不知道等价物是什么。 If you're using msbuild or dotnet pack, but you also have your own nuspec file, I recommend against it.如果您使用的是 msbuild 或 dotnet pack,但您也有自己的 nuspec 文件,我建议您不要使用它。 Anything you want to do in the nuspec should be possible by setting the right properties or item attributes in your csproj, and let the pack targets generate the nuspec automatically.通过在 csproj 中设置正确的属性或项目属性,您可以在 nuspec 中执行任何操作,并让包目标自动生成 nuspec。 When you have your own nuspec, parts of nuget's auto-generation gets turned off, so you may be making things harder for yourself.当您拥有自己的 nuspec 时,部分 nuget 的自动生成功能会关闭,因此您可能会让事情变得更困难。

My memory of nuget pack on old style csproj files is that nuget will automatically make a project reference a nuget dependency as long as the referenced project has a <project name>.nuspec file in the same directory as the <project name>.csproj file (I'm almost certain that it's documented somewhere on docs.microsoft.com/nuget).我对旧式 csproj 文件上的nuget pack记忆是只要引用的项目在与<project name>.csproj文件相同的目录中有一个<project name>.nuspec文件,nuget 就会自动使项目引用成为 nuget 依赖项(我几乎可以肯定它记录在 docs.microsoft.com/nuget 上的某处)。 However, if your dependant project is a SDK style project (like is needed for .NET Core or .NET Standard projects), then I already advised against using a nuspec file with those projects, so you should really consider using the pack targets and stop using nuget pack .但是,如果您的依赖项目是 SDK 样式的项目(例如 .NET Core 或 .NET Standard 项目需要),那么我已经建议不要在这些项目中使用 nuspec 文件,因此您应该真正考虑使用包目标并停止使用nuget pack

The second part of my answer will directly answer your question, which is about how to make a project reference a package reference on certain builds.我的回答的第二部分将直接回答您的问题,即如何在某些构建上使项目引用成为包引用。 Firstly, you need to use pack targets, either by using a SDK style project or by referencing the NuGet.Build.Tasks.Pack package.首先,您需要使用包目标,通过使用 SDK 样式项目或通过引用 NuGet.Build.Tasks.Pack 包。 This way, you don't use a nuspec file, and everything is defined in your csproj , which is just a MSBuild file.这样,您不使用nuspec文件,所有内容都在您的csproj定义,它只是一个 MSBuild 文件。 MSBuild has conditions, so hand edit your csproj and make your project reference have a certain condition and have the package reference have the opposite condition. MSBuild 有条件,所以手动编辑你的 csproj 并使你的项目引用有一定的条件,而包引用有相反的条件。 I suggest use a variable like $(CI), so you can test the pack using msbuild -t:pack -p:CI=true , and on your CI machine just set CI as an environment variable to true.我建议使用像 $(CI) 这样的变量,这样你就可以使用msbuild -t:pack -p:CI=true测试包,在你的 CI 机器上,只需将 CI 作为环境变量设置为 true。 Since NuGet already has functionality built-in for making project references into nuget dependencies, I recommend using that, and not switching between package and project references, so I'm not going to give a copy-paste example on how to do this.由于 NuGet 已经内置了将项目引用转换为 nuget 依赖项的功能,因此我建议使用它,而不是在包和项目引用之间切换,因此我不打算提供有关如何执行此操作的复制粘贴示例。 But if this isn't a case of a XY-problem and you really need to do this, then I've already given enough pointers for you to be able to figure out how to do the rest.但是,如果这不是XY 问题的情况并且您确实需要这样做,那么我已经为您提供了足够的指示,让您能够弄清楚如何完成其​​余的工作。

NuGet CLI has issues with dependencies for PackageReferences and project references (only when the project is a .net Core or .net Standard too?) when not using .nuspec files.在不使用.nuspec文件时,NuGet CLI对 PackageReferences和项目引用的依赖项有问题(仅当项目也是.net Core或 .net Standard 时?)。

Use dotnet pack or msbuild -t:pack to include the project reference as a nuget dependency.使用dotnet packmsbuild -t:pack将项目引用包含为 nuget 依赖项。 This also resolves issues for PackageReferences not being written as dependencies.这也解决了 PackageReferences 未作为依赖项编写的问题。

Assuming your .net framework project is out-of-the-box from Visual Studio, you'll need to reference the Nuget.Build.Tasks.Pack nuget package to access the necessary targets.假设您的 .net 框架项目是从 Visual Studio 开箱即用的,您将需要引用Nuget.Build.Tasks.Pack nuget 包来访问必要的目标。 We write this data into the .csproj file with powershell on the build server before any nuget restore so that is isn't forgotten about for new full framework projects (which we are trying to get away from creating).在进行任何 nuget 恢复之前,我们使用构建服务器上的 powershell 将此数据写入 .csproj 文件,以便不会忘记新的完整框架项目(我们正试图摆脱创建)。 As @zivkan mentioned, you will probably want to正如@zivkan 提到的,你可能想要

set PrivateAssets to all to avoid this package becoming a nuget dependency将 PrivateAssets 设置为 all 以避免此包成为 nuget 依赖项

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

Changing a project reference to a NuGet package reference on build在构建时将项目引用更改为 NuGet 包引用

I am afraid you could not convert the project reference to the nuget package reference during building.恐怕您无法在构建过程中将项目引用转换为 nuget 包引用。 That because they are two different ways of dealing with references.那是因为它们是处理引用的两种不同方式。 Although there are now some extensions that can convert a project reference to a nuget package reference, they need manual operation, we could not use it during the building.虽然现在有一些扩展可以将项目引用转换为nuget包引用,但它们需要手动操作,我们在构建过程中无法使用它。

Check the another thread for some more details.检查另一个线程以获取更多详细信息。

So, we could not change the project reference .NET Standard (2.0) library to a NuGet package reference and add to your .NET Framework (UI) library on build .因此,我们无法将项目引用.NET Standard (2.0) library更改为 NuGet 包引用并在构建时添加到您的 .NET Framework (UI) 库中。

Personally, to resolve this issue, you could use reference the .net Standard (.netSrd) project as nuget package reference on your local, when you have updated version number nuget package for .net Standard project, you could update this package in your Azure Artifacts, and use custom nuget task command to call nuget update command to update the packages to the latest version when you build your .NET Framework (UI) library.就个人而言,要解决此问题,您可以在本地使用引用 .net Standard (.netSrd) 项目作为 nuget 包引用,当您更新了 .net Standard 项目的版本号 nuget 包时,您可以在 Azure 中更新此包Artifacts,并在构建 .NET Framework (UI) 库时使用自定义 nuget 任务命令调用nuget update命令将包更新到最新版本。

Check the details info from:检查详细信息:

Update NuGet package to last version after build in VSTS 在 VSTS 中构建后将 NuGet 包更新到最新版本

Hope this helps.希望这可以帮助。

If you are using the new csproj format (designed for .NET Core but can work with any .NET) then it's pretty simple.如果您使用新的 csproj 格式(专为 .NET Core 但可以与任何 .NET 一起使用),那么它非常简单。

In the projects you want to be released as NuGet packages you have to add in the csproj the following:在要作为 NuGet 包发布的项目中,您必须在 csproj 中添加以下内容:

<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

Apart from that you only have to reference your other projects with ProjectReferences.除此之外,您只需使用 ProjectReferences 引用您的其他项目。 MSBuild will build everything, and when publishing the NuGet packages it will change the ProjectReferences to PackageReferences. MSBuild 将构建所有内容,并在发布 NuGet 包时将 ProjectReferences 更改为 PackageReferences。

If you have a ProjectReference, it will override any package references to the same package ID in the restore graph.如果您有 ProjectReference,它将覆盖对还原图中相同包 ID 的任何包引用。

Source: Resolve package references to projects (dotnet github issue)来源: 解决对项目的包引用(dotnet github 问题)

I tried this myself (added both the ProjectReference and the PackageReference in the csproj file).我自己尝试过(在 csproj 文件中添加了 ProjectReference 和 PackageReference)。 It successfully builds and the output NuGet file contains the dependency to the other NuGet package.它成功构建并且输出 NuGet 文件包含对其他 NuGet 包的依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM