【问题标题】:How to create "NuGet Package Management Project" for .NET Standard?如何为 .NET Standard 创建“NuGet 包管理项目”?
【发布时间】:2019-10-28 17:28:30
【问题描述】:

我想使用一个项目,其唯一的一点是引用 NuGet 包,然后 Visual Studio 将下载和更新这些包(以及它们的所有依赖项)(目前,对我来说是 2017 年)。1(这有点类似于another question 中描述的内容。)

当我创建一个 .NET Framework 4.7.1 项目时,我可以使用 VS 的 Manage NuGet Packages 功能来选择所需的包,VS 会将包下载到解决方案目录中,并且我的构建脚本可以根据在.csproj 文件(<HintPath> 等)中找到的信息确定将哪些 DLL 复制到我的实际项目文件夹中。

但是,当我对 .NET Standard 2.0 项目执行相同操作时,VS 将使用新的简化 .csproj 格式。它所提到的(显式地和传递地)所需的包都是一个 <PackageReference> 元素,其中只有我明确选择引用的每个包的包名和版本。我的脚本不足以将引用移植到目标 .csproj 文件中。2

在针对 .NET Standard (2.0) 时,是否还有通过这样一个虚拟项目管理 NuGet 包的好方法?


1:造成这种情况的原因包括大量单独的解决方案,其中许多需要相同的包,并且并非所有开发人员都应该自己管理这些包,以及不支持 NuGet 的环境他们自己的(比如 Unity 游戏引擎,所以a separate project to manage and pull NuGet references is the way to go)。

2:即使Unity项目中配置的“API Compatibility Level”是“.NET Standard 2.0”,Unity生成的.csproj文件也会使用“old-style”verbose格式(并且实际上是针对 .NET Framework 4.*,似乎)并因此期望引用库的显式路径。

【问题讨论】:

  • 你要的nuget package management project是用来管理.net标准项目还是同时管理.net标准、.net fx和.net核心项目?
  • @LanceLi-MSFT:坦率地说,我不太清楚 - 在手头的 Unity 案例中,我认为我需要它从包中检索与 .NET Standard 2.0 兼容的库,即使目标从技术上讲,该项目似乎是一个 .NET Framework 项目。我更喜欢对所有目标都以相同方式工作的解决方案(以尽量减少在未来开发例如 Core 时的重新配置),但如果这不可能,.NET Standard(和 Unity?)兼容的解决方案应该成为这个问题的焦点
  • 您能否编辑问题标题并考虑改写您的问题正文。如果您忽略问题的两个脚注,答案就是“创建一个 .NET Standard 类库”。其他一切都适用于几乎所有非 Unity 的 .NET 项目。还要考虑标记统一,因为您的问题不是通用的 .NET 并且非常特定于 Unity
  • @zivkan:您好,我认为这里可能存在误解。如前两段所述,要求以能够自动找到/复制所有必需库的方式下载包及其依赖项,例如通过脚本。第三段描述了在使用 .NET Standard 项目时情况并非如此。虽然 Unity 可能是一个常见的例子,但在任何我不能依赖丢失的包在以后检索的环境中(例如在构建期间),都需要这样的过程。不过,我会尝试澄清问题描述。
  • 应该由 .NET 构建系统来解决这个问题。只有创建自己的项目类型的人,所以在我个人看来,Unity 是缺乏的。查看他们的项目系统,它几乎是一个“正常”的 .NET 项目,因此可以重用所有正常的 .NET 构建系统功能来自动获取正确的 DLL,但他们选择禁用项目和包引用。

标签: .net visual-studio-2017 nuget .net-standard


【解决方案1】:

正如我在对该问题的评论中提到的那样,忽略问题脚注,这看起来像是一个通用的 .NET 问题,我希望谷歌会向进行通用搜索的人推荐此页面,而不仅限于 Unity,而且不会在阅读大部分问题之前,对于阅读该问题的其他人来说很明显,它是 Unity 特有的。因此,我将开始为通用 .NET 开发提供答案。

如果涉及的所有项目都使用PackageReference,那么不需要做任何特别的事情。只需从新项目模板创建 .NET Standard 类库,将包引用添加到所需的包,然后从要使用该组 NuGet 包的应用创建对类库的项目引用。

如果你有一个没有任何包的非 SDK 风格的项目,那么你应该添加<PackageRestoreStyle>PackageReference</PackageRestoreStyle>。原因是 PackageReference 在 NuGet 启动多年后被添加到 NuGet,使用包的原始方式是 packages.config。因此,当一个项目没有选择加入PackageReference 恢复样式时,它默认为packages.config。请参阅下一段。

如果您有一个使用packages.config 的非SDK 样式项目(或没有包并且没有选择使用PackageReference 恢复样式),那么这种方法可能不起作用。构建系统将构建应用程序的程序集,并可能复制在csproj 中直接引用的所有引用,这意味着它将获取您的类库 dll 以及直接引用的任何 nuget 包。但是,由于应用程序 csproj 不知道您的类库的 NuGet 包,因此它们不会被复制。通常,类库引用它使用的包,.NET 构建系统将使用名为 ResolveAssemblyReferences 的东西来查看类库 dll,查看它具有哪些依赖项,然后复制这些 dll。但是,在这种情况下,类库项目没有任何已编译的依赖项,因为它从未使用项目引用的任何 NuGet 包。

这就是 NuGet 和 .NET 团队鼓励客户迁移到 PackageReference 的原因之一。有很多问题,比如传递依赖,以及 <HintPath> 在项目移动时会变坏,只要您使用的项目类型支持它,它们就会更好地工作。

现在,鉴于问题脚注提到提问者希望为 Unity 项目执行此操作,我将给出一个我希望有效的答案。请注意,当我在 NuGet 客户端团队工作时,我对 Unity 一无所知,今天早上浪费了大约 2 个小时来安装它并尝试了解它的功能,只是发现 Unity 似乎不支持 NuGet 或项目参考。

所以我的建议是:

使用 dotnet publish 让 .NET 构建系统将所有相关 dll 复制到一个文件夹中,然后您可以在 Unity 项目中引用该文件夹

多目标您的类库以同时面向 .NET Standard 2.0 和 .NET Framework 4.7.1(调整 .NET Framework 版本以使用与 Unity 项目使用的相同的版本)。通过将<TargetFramework>netstandard2.0</TargetFramework> 更改为<TargetFrameworks>netstandard2.0;net471</TargetFrameworks> 来执行此操作(请注意,XML 元素的末尾添加了s)。现在,当您构建类库时,.NET SDK 将在bin\ 目录中创建两个目录,一个用于每个目标框架。至少目前看来,net471 目录获取了所有的 dll,类似于非 SDK 风格的项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-07
    • 2019-09-01
    • 2018-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    相关资源
    最近更新 更多