【问题标题】:C# project, compiler complaining missing reference to log4netC# 项目,编译器抱怨缺少对 log4net 的引用
【发布时间】:2019-03-13 13:52:19
【问题描述】:

我正在使用 Visual Studio 2017 构建一个大型 C# 项目(解决方案中有 200 多个项目)。在编译其中一个项目时,我遇到了很多错误,如下所示:

error CS0012: The type 'BufferingAppenderSkeleton' is defined in an assembly that is not referenced. You must add a reference to assembly 'log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=1b44e1d426115821'.

然而,有问题的项目确实引用了 log4net 1.2.11。唯一可疑的是在 log4net 的包路径中找到的 net40-full:“C:\XXXX\Src\packages\log4net.1.2.11\lib\net40-full\log4net .dll"

在项目的 package.config 中,它包含这一行:

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

在它的 app.config 中,它包含这一行:

      <dependentAssembly>
    <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral"/>
    <bindingRedirect oldVersion="0.0.0.0-1.2.11.0" newVersion="1.2.11.0"/>
  </dependentAssembly>

不知道是不是 .net 版本(4.0 与 4.61)不匹配导致了编译错误?

C# 不是我的主要专业领域,但我的理解是 nuget 会查看这些配置文件以下载所需的包,在本例中为 log4net。那它怎么下载的是4.0版本而不是4.6.1的呢?

【问题讨论】:

  • 可能它给了你这个问题,因为用于 log4net 版本 1.2.11 的 NuGet 不再存在。您应该将其至少升级到 2.0.0 版本(仍然具有 1.2.11.0 版本的 dll,但 publicKeyToken 不同)。

标签: c# visual-studio nuget log4net


【解决方案1】:

我的理解是,nuget 会查看这些配置文件以下载所需的包,在本例中为 log4net。

NuGet 的工作只是下载包并提取其中的任何内容,至少在 package.config 项目的还原方案中是这样。 packages.config 文件中的targetFramework 属性只被the nuget client 写入,从不读取。我不知道它的目的或意图是什么。无论如何,我相信targetFramework 的值只是你的项目在安装包时使用的.NET Framework。

那它怎么下载的是4.0版本而不是4.6.1的呢?

背景信息,如果你真的不在乎,请跳到下一段。如果您转到 nuget.org 上的包页面,您会在版本历史记录中看到未显示 1.2.11。但是,如果您查看其他版本的 URL,您可以猜到 the URL for version 1.2.11。快速偏离主题的评论,Fabio M 很接近,但说包不再存在并不完全正确。 “nuget.org does not support permanent deletion of packages. Doing so would break every project depending on the availability of the package, especially with build workflows that involve package restore.”。在包版本页面上,有一条消息说“所有者已取消列出此包。这可能意味着该包已弃用或不应再使用”。

回到我的观点,一旦您访问此 URL,请将 nuget.org 中的 n 更改为 f 以查看 the package version on fuget.org。在框架旁边,您可以看到包支持的框架列表。 net40 是包支持的最高版本。

所以,NuGet “下载 4.0 版本”的原因是因为这是 nuget 包提供的与您的项目兼容的最接近的版本。 .NET 通常被认为是向前兼容的,因此 net45 二进制文件在 net462 运行时上工作,因此当您的项目使用较新版本时,通常可以使用 net45 二进制文件。

最后,关于您遇到的错误,正如我在第一段中所说,在 packages.config 项目中,nuget 的工作只是下载和解压缩包。在安装时,它会向 csproj 添加一些信息,以便编译器可以尝试查找 dll。因此,如果您查看您的 csproj,您应该会找到对 log4net.dll 的引用,它将包含编译器使用的提示路径。如果该提示路径错误,那么您将看到您看到的错误。这在项目在目录结构中移动但不重新安装包时最常见。例如,如果 repo 结构原本是“project\project.csproj”,现在改为“src\project\project.csproj”,则提示路径为“..\packages\log4net.1.2.11\lib\net45\ log4net.dll”是错​​误的,因为需要添加一个额外的“..\”,所以包文件夹的相对路径是正确的。提示路径错误可能还有其他原因,但这是最常见的原因。

【讨论】:

  • The targetFramework attribute in the packages.config file is only written, never read by the nuget client. I have no idea what it's purpose or intention was. 尝试创建一个 .Net 2.0 项目并拉入一个目标框架为 4.6.1 的 Nuget 包。如果不将项目升级到 4.6.1+,您将无法做到这一点。
  • @Amy 这是由于 NuGet 在编写 packages.config 文件之前所做的资产选择,并且独立于编写 packages.config 文件。如果和资产选择有关,那么它应该写从nupkg中选择的目标框架,而不是安装时项目的TFM(如果不重新更改,可能与项目的TFM不同)安装包)
  • 此外,您可以手动编辑 packages.config 文件,更改 TFM,当您恢复时,没有什么不同。
  • @zickan,非常感谢您的详细解释!我查看了 .csproj 文件,发现它的 log4net 路径与物理位置的路径不一致。正如我从您的回答中了解到的那样,.csproj 文件中的路径是基于 nuget 下载/精确编写的提示?您还建议根本原因是由于未重新安装软件包。但我认为它不适合我的情况:该项目是从 git repo 签出的,签出时没有包,包是由 nuget 动态创建的。这样的问题应该首先存在。
  • 当您克隆存储库并需要获取 nuget 包时,这称为还原。安装包是当您转到 Visual Studio 中的“管理 Nuget 包”窗口时,选择一个包并单击“安装”或“升级”。提示路径仅在您执行管理 NuGet 包时更改,而不是在您从新克隆的存储库还原包时更改。同样,重新安装意味着使用 VS UI 卸载并重新安装包,或者使用 NuGet 包管理器控制台(VS 中的 nuget powershell 控制台)中的Install-Package -reinstall -project {project name}
猜你喜欢
  • 2011-01-08
  • 2021-11-30
  • 2017-06-21
  • 1970-01-01
  • 2015-10-31
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多