C# 项目,编译器抱怨缺少对 log4net 的引用

C# project, compiler complaining missing reference to log4net

我正在使用 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 vs. 4.61)不匹配导致的编译错误?

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

my understanding is that nuget looks into those config files to download needed packages, in this case, log4net.

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

Then how come did it download the 4.0 version rather than that of 4.6.1?

背景信息,如果你真的不在乎,请跳到下一段。如果您转到 nuget.org 上的软件包页面,您会在版本历史记录中看到未显示 1.2.11。但是,如果您查看其他版本的 URL,您可以猜测 the URL for version 1.2.11. Quick off-topic comment, Fabio M was close, but not quite correct in saying the package doesn't exist any more. "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.”。在包版本页面上,有一条消息说 "The owner has unlisted this package. This could mean that the package is deprecated or shouldn't be used anymore"。

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

所以,之所以选择 NuGet "downloaded the 4.0 version",是因为这是 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”是错​​误的,因为需要添加额外的“..\”,所以包文件夹的相对路径是正确的。提示路径错误可能还有其他原因,但这是最常见的原因。