visual studio / nuget如何决定下载/确切包的版本?

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

这是一个C#项目。据我所知,nuget咨询了package.config以获取下载/解压缩包的信息。但是我注意到它为不同的.net平台下载了多个版本。例如,在packages.config中:

<package id="log4net" version="1.2.11" targetFramework="net461"/>

nuget将所有版本从net10下载到net40。此外,.csproj文件中指定的位置与物理位置中的位置不一致。

在上面的示例中,.csproj中的位置类似于:

src/packages/lognet.1.2.11/lib/log4net.dll

但是,dll的物理位置是:

src/packages/log4net1.2.11/lib/netXX-full/log4net.dll

如前所述,XX可以是10到40,下载并提取了多个版本的log4net。

由于不一致,该项目注定要失败,引用包未找到错误。

我该怎么做才能解决这个问题?

仅供参考:几天前我问了一个相关但又不同的问题。

C# project, compiler complaining missing reference to log4net

.net visual-studio nuget log4net
1个回答
1
投票

“直接和重点”答案:你不应该担心它。当您在项目中安装或升级软件包时,NuGet会告诉项目系统要在csproj中放入什么。请注意,这与恢复包不同。在packages.config项目中安装软件包意味着Visual Studio将修改packages.config文件和csproj文件。如果您的计算机上没有nuget软件包,当NuGet下载并解压缩它时,它称为恢复,而不是安装。在上一个问题中,你说你克隆了别人的回购,你正试图让它建立起来。您可以问他们csproj与nuget.org上的log4net包不匹配的原因/原因。或者在Visual Studio中,按ctrl-q进入搜索,键入“package manager console”并选择它。初始化后,在“默认项目”下拉列表中选择带有错误log4net引用的项目,然后键入Update-Package -reinstall。这应该解决它。或者,您可以在解决方案资源管理器中右键单击该项目,选择“管理NuGet包”,卸载log4net,然后重新安装。你也可以考虑migrating from packages.config to PackageReference,它没有package.config所具有的这个提示路径问题。

详细的答案:使用NuGet时,“版本”一词通常是指包版本,在本例中为1.2.11。看看package page on nuget.org,在版本历史下我们可以看到其他版本,如1.2.10,2.0.0,2.0.1直到2.0.8。除非您有多个项目,每个项目都引用了不同版本的软件包,否则NuGet不会下载多个版本。

.NET有不同版本的运行时,其中一些版本与其他版本不兼容,但这些版本称为Target Framework Monikers(TFM),尽管那些不为Microsoft工作的人往往只是将它们称为目标框架或类似的东西。 。它类似于其他托管运行时或脚本语言,如Java,Python,PHP等,但可能更复杂,因为过去创建了大量TFM,主要用于具有不同功能的不同移动设备。此外,Windows运行时分为3个“系列”,其中TFM向后兼容,但仅在同一“系列”中。 Nuget Client has a complex mapping of compatible TFMs用于为项目选择NuGet包中最接近的兼容TFM。

包可能包含用于不同TFM的多个dll的另一个原因是因为他们希望在较新的TFM中使用较新的API,同时仍允许针对较旧的TFM的项目在没有新API的情况下使用该包。例如,虽然net45,net46,net47和很快net48都与net40兼容,但net40没有async-await。因此,一个软件包可能有一个net40 dll,因此针对net40的项目仍然可以使用该软件包,但该软件包还可以包含带有额外异步API的net45 dll。 net1x,net 2x和net3x是如此古老,(因为net40和net45),包很少为这些旧版本提供dll。但是,log4net 1.2.11于2011年发布,当时这些较旧的TFM可能仍然很常见,因此值得提供兼容性。

所以,你在log4net包的lib文件夹中看到的不是log4net的不同版本,它实际上是log4net的相同版本,但是为不同的TFM编译。这增加了可以使用该包的项目数量。

您正在使用的项目有一个不存在的HintPath有几种可能性。鉴于您目前提供的信息信息,听起来像是有人手动编辑了csproj,或者有人创建了自己的log4net v1.2.11 nuget包,它在nupkg中的不同位置与nuget上的包相比具有dll。有机NuGet包被设计为不可变的意味着下载具有特定包ID(名称)的nupkg,并且包版本应该与具有相同包ID +来自任何其他NuGet订阅源的所有其他nupkgs相同。如果不是这样,当NuGet从安装包的人恢复来自不同来源的包时,您可能会出现构建错误。

最后,带有packages.config的NuGet不能手动编辑。您不应自己编辑和保存csproj中的packages.config文件或References或HintPath。使用NuGet Package Manager UI或Package Manager控制台安装,卸载和升级软件包。 NuGet客户端中有很多逻辑,而不仅仅是资产选择,如果软件包使用特定功能,您将会出错。

在Visual Studio 2017中,NuGet添加了一种新的方法来引用包,称为PackageReference。您可能需要转到工具 - >选项,找到NuGet包管理器 - >常规,并更改默认包管理格式或启用“允许在第一个包安装时选择格式”。也可以右键单击许多项目类型,并可以选择迁移到PackageReference,但尚未为所有项目类型(主要是ASP.NET)启用此选项。 PackageReference不支持packages.config支持的某些功能,而且某些项目类型也不支持PackageReference。但在最常见的情况下它是受支持的,如果你可以使用它,它有几个优点,包括不再在你的csproj中放置一个提示路径并避免你当前遇到的特定问题(在恢复时NuGet写一个文件obj\project.assets.json其中包含编译器使用的所选资产的路径,这意味着如果更改源代码存储库结构,只需执行NuGet还原即可修复它,而使用packages.config则可能需要重新安装每个项目中的每个包。使用.NET Core引入的新SDK样式的项目根本不支持packages.config,无论值得什么。

哇,我漫步的时间比我想象的要长得多。我希望它对你有所帮助。

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