NuGet:对运行时文件夹中的程序集的引用未添加

时间:2018-09-19 03:18:04

标签: nuget

我有一个针对两个不同的操作系统/框架的项目:

    Windows和上的
  1. net461
  2. netcoreapp2.0在OSX上

我正试图弄清楚如何为NuGet正确打包它。根据{{​​3}},我应该能够像这样打包它们:

/runtimes/win/lib/net461/myassembly.dll
/runtimes/osx/lib/netcoreapp2.0/myassembly.dll

当我将NuGet包添加到另一个项目时,打包的程序集不会添加为对目标项目的引用。

然后我读到某个地方,您还需要将参考库添加到/ref文件夹中,因此我尝试了以下操作:

/runtimes/win/lib/net461/myassembly.dll
/runtimes/osx/lib/netcoreapp2.0/myassembly.dll
/ref/net461/myassembly.dll
/ref/netcoreapp2.0/myassembly.dll

在这种情况下,将程序集添加为对目标项目的引用,我可以对其进行构建,但是所需的程序集不会复制到输出文件夹中。

关于这一切的文档非常含糊,我很迷茫。

我想念什么?


相关的NuGet问题:this post


更新:我整理了一个https://github.com/NuGet/Home/issues/7316,以演示我正在尝试实现的目标。特别是请参阅自述文件的底部,标题为“ NuGet包装”。

6 个答案:

答案 0 :(得分:9)

这是我最终想出的/猜到的(因为最好的是,我可以告诉我其中没有官方文件)

  • 添加到/ runtimes文件夹的文件不会自动添加为对目标项目的引用。
  • / ref和/ runtime文件夹应相互结合使用,并且仅用于.NET Core目标。尽我所能,.NET Framework目标显然不支持这些文件夹。
  • / ref文件夹用于编译时引用,此处添加的任何内容都将添加为对目标项目的引用。
  • / ref文件夹中的程序集不需要实现-每个公共API都可以抛出未实现的异常。但是实际上,您通常只复制一个实现程序集的副本,并将其声明为编译时API。
  • 我已阅读(但尚未进行自我测试),/ ref文件夹中的程序集必须是“ Any CPU”构建的。必要时,您可以使用CorFlags实用工具为此实现程序集打补丁。
  • / runtimes文件夹用于为/ ref文件夹中包含的所有引用提供实现程序集。这些程序集在运行时和部署期间使用。
  • / runtimes文件夹可以包含其他程序集,这些程序集仅在运行时需要,而在客户端项目中无需查看。这些额外的程序集不会作为参考包含在目标项目中,但可用于运行/部署。
  • 正如其他人所提到的,/ runtimes文件夹中的文件不会复制到构建的输出文件夹中。取而代之的是将配置文件放置在该文件中,这些文件告诉运行时如何从NuGet缓存中找到/ runtimes文件。
  • 对于.NET Framework目标(即net461),只需使用/ lib文件夹,因为除了Windows之外,没有其他用于.NET的运行时。

将所有内容放在一起,我的原始示例应该看起来像这样:

/lib/net461/myassembly.dll                       (net461/Windows Compile and Runtime)
/runtimes/osx/lib/netcoreapp2.0/myassembly.dll   (netcore/OSX Runtime)
/runtimes/win/lib/netcoreapp2.0/myassembly.dll   (netcore/Win Runtime)
/ref/netcoreapp2.0/myassembly.dll                (netcore/* Compile Time)

答案 1 :(得分:5)

我花了很多时间在Mac上的Visual Studio和VS Code中的OSX上尝试您的项目。我会尽量坚持事实观察,而不会陷入“为什么不这么做X”的问题。

  • runtimes/{rid}/lib/{tfm}/*.dll路径看起来不错
  • target="lib/{tfm}/..."程序集被自动引用,runtimes/...未自动引用
  • 使用netstandard的目标框架似乎会使您的软件包在netcoreappnetstandard项目中都可以工作(例如,使用target="lib/netstandard1.6/...")。比较with this
  • runtimes/似乎适用于您将在运行时加载的平台相关程序集。例如,runtimes/win-x64/native/runtimes/win-x86/native/)中的32/64位本机程序集已加载AssemblyLoadContextanother post by McMaster
  • 为Windows和OSX使用单独的slns,或引用与平台无关的项目的单独的特定于平台的项目(例如Xamarin)将避免某些配置问题
  • 我在target="ref/..."上未找到任何文档,但是您可以添加Explicit Assembly <references>(在nuspec <metadata>块内部)
  • 打包的程序集不会出现在输出目录中,但是当准备使用dotnet publish分发时,它们将被包括在内:

答案 2 :(得分:3)

.NET Core和.NETSTANDARD不会将依赖项复制到输出目录,而是使用deps.json映射它们,它们指向本地NuGet缓存的相对路径。

答案 3 :(得分:0)

您可以尝试针对.NET Standard 2.0而不是net461和netcoreapp2.0吗?针对netstandard2.0构建的库应与.NET Core 2.0和.NET Framework 4.6.1配合使用:https://docs.microsoft.com/en-us/dotnet/standard/net-standard

答案 4 :(得分:0)

您是否正在使用新的csproj格式?如果是这样,它已经内置了对多个目标框架的支持。

例如,对具有以下内容的.csproj文件运行dotnet pack

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <TargetFrameworks>net461;netcoreapp2.1;netstandard2.0</TargetFrameworks>
  </PropertyGroup>    
</Project>

将生成一个适用于.NET Framework 4.6.1,.NET Core 2.1和.NET Standard 2.0的.nupkg。

然后根据可用的工具,使用各种技巧为每个框架包括特定的部分。

答案 5 :(得分:0)

我正在尝试解决相同的问题。 您提出的解决方案效果很好,但是有一个问题... Win和net46的情况很清楚。现在,我需要为Win和Linux的netcoreapp添加对项目中程序集的引用。问题是这是一个具有相同名称的不同程序集。那些我的包裹看起来像这样:

/lib/net461/myassembly1.dll                       (net461/Windows Compile and Runtime)
/runtimes/ubuntu/lib/netcoreapp2.0/myassembly2.dll   (netcore/Ubuntu Runtime)
/runtimes/win/lib/netcoreapp2.0/myassembly1.dll   (netcore/Win Runtime)
/ref/netcoreapp2.0/???

更新:实际上,myassembly1.dll和myassembly2.dll都称为myassembly.dll。但是为了显示一个是为Windows组装的,而另一个是为Linux组装的,我将在这里保留这样的名称。

最有趣的是,我尝试将任何程序集都放在ref文件夹中,并且它在Windows和Linux上均可工作。 此版本可在两个系统上使用

/lib/net461/myassembly1.dll   
/runtimes/ubuntu/lib/netcoreapp2.0/myassembly2.dll 
/runtimes/win/lib/netcoreapp2.0/myassembly1.dll  
/ref/netcoreapp2.0/myassembly1.dll

这也是

/lib/net461/myassembly1.dll   
/runtimes/ubuntu/lib/netcoreapp2.0/myassembly2.dll 
/runtimes/win/lib/netcoreapp2.0/myassembly1.dll  
/ref/netcoreapp2.0/myassembly2.dll

但是我认为这是不对的,我在某个地方错了。