nuget软件包中的.netstandard2.0和.netframework47 DLL的混合-.netstandard不可用

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

首先,我不知道我在做什么,从根本上来说是一个错误的主意,所以答案可能是不做这个,而是去。

我有一个要从.nuspec文件创建的程序包,在它的“文件”部分中,它包含对.net标准和.net框架DLL的引用。它还依赖于.netstandard20和.netframework47。

这是因为遗留库是在框架中编写的,而新库是在标准库中编写的。

[我们有一个耗时的项目(实际上是几个),用.netframework 4.7编写,需要处理两组DLL。我已将项目更改为使用PackageReference而不是packages.config,并且Visual Studio在“引用”部分中显示了对包的引用(而不是各个名称空间)。当我构建时,.netframework DLL被复制到bin文件夹中,而不是.netstandard DLL。

我创建了一个草稿项目来隔离问题,并且在那里也看到了同样的情况。该项目基本上只是拒绝承认标准之一。如果我将.netstandard DLL中的类型的using语句添加到类中,它只会在其下放一个红色的字形,并告诉我它在名称空间中不存在。

[有人建议我将.netstandard DLL分解成它们自己的NuGet包,是答案还是我缺少什么?

这里有一些例子..

。nuspec文件:

<?xml version="1.0" encoding="utf-8"?>
<package >
  <metadata minClientVersion="2.5">
    <!-- other tags removed for brevity -->
    <dependencies>
      <group targetFramework=".NETStandard2.0"></group>
      <group targetFramework=".NETFramework4.7">
        <dependency id="NLog" version="3.1.0.0" />
      </group>
    </dependencies>
  </metadata>
  <files>
    <file src="..\Src\MyProj1\bin\Release\netstandard2.0\NetStandardClass.dll" target="lib\netstandard2.0" />
    <file src="..\Src\MyProj2\bin\Release\NetFrameworkClass1.dll" target="lib\net47" />
    <file src="..\Src\MyProj3\bin\Release\NetFrameworkClass2.dll" target="lib\net47" />
  </files>
</package>

该包被引用为包,而不是其中的单个类型:

enter image description here

如果我尝试手动添加引用NetStandardClass命名空间的using语句,则会将其标记为错误

enter image description here

程序包本身包含所有3个DLL:

enter image description here

然而,当我构建项目并检查bin文件夹时,NetStandardClass DLL不存在:enter image description here

c# dll nuget .net-4.0 .net-standard-2.0
1个回答
0
投票

[有人建议我将.netstandard DLL分解成它们自己的NuGet包,是答案还是我缺少什么?

基本上,是的,将包拆分是答案。另一种可能性是将netstandard程序集移动到net47文件夹中,或者将net47程序集移动到netstandard2.0文件夹中,但是任何一种方式都有可能出现问题。尽管解决方案是重新编译所有程序集,以便它们都使用相同的目标框架,但这也有其自身的问题。

如果您已经阅读了NuGet文档,并得出结论,您尝试执行的操作应该起作用,请指出哪些文档使您相信,因此我可以更新文档并尝试消除混乱。

关于NuGet为什么支持具有多个目标框架文件夹的软件包的第一件事是,软件包可能希望在可能的地方使用新的框架功能,但使用较旧的框架对软件包的用户提供支持。因此,程序包作者需要其程序集的多个版本,具体取决于哪个版本与其用户项目兼容。因此,关键是NuGet需要根据项目使用的目标框架标记(TFM)从软件包中选择资产。 NuGet实际进行资产选择的方式如下:

NuGet外观是程序包中存在哪些TFM文件夹,以获取程序包支持的TFM列表。通常,它查找lib/<tfm>/ref/<tfm>文件夹,但是contentFiles/<tfm>build/<tfm>文件也可能相关。请注意,它不会查看任何文件名。尚未考虑在lib/net47/*.dlllib/netstanard2.0/*.dll下存在哪些程序集。

一旦有了此包TFM列表,它就会查看项目TFM,并选择“最佳” TFM。对于具有多个目标的SDK样式的项目,每个项目TFM都会执行一次。 “最佳” TFM表示相同的“家族”(net *项目始终选择net *资产(如果可用)。仅当不存在net *程序集时,netstandard兼容的.NET Framework TFM才会寻找netstandard *资产)。

一旦为项目的TFM选择了软件包TFM,则NuGet会选择lib/<tfm>/*.dllref/<tfm>/*.dllcontentFiles/<tfm>/<lang>/*build/<tfm>/<package_id>.<props|targets>等所有文件。

因此,您可以看到,如果您的程序包中包含lib/net47/assembly1.dlllib/netstandard2.0/assembly2.dll,NuGet将仅选择这两个程序集之一,而决不会同时选择这两个程序集,这取决于net47或netstandard2.0是否与该项目更兼容。 >

尽管如果您对NuGet进行每个TFM的TFM选择,而不是先选择TFM,然后仅选择该文件夹中存在的程序集,对您来说似乎很理想,但是请考虑在程序包中添加附加的辅助程序实用程序以“填充”旧的TFM时,软件包在较新的TFM中使用的功能。较新的TFM不需要此帮助程序实用程序,因此NuGet最好不要选择它。

NuGet团队建议为每个程序集创建一个程序包,在这种情况下,永远不会发生此问题,因为NuGet会为每个程序包进行资产选择,并且假设每个程序包都编写正确,则所有内容都会正确选择。如果您坚持将所有程序集捆绑在一个程序包中,那么从我上面的描述中,我希望您需要将所有程序集放在一个TFM文件夹中,但是由于不同的程序集是针对不同的TFM编译的,因此存在潜在的问题,尤其是如果某些开发人员使用的Visual Studio的旧版本可能不支持.NET Standard。我强烈建议至少为每个TFM创建一个程序包,或重新编译所有程序集以使用同一TFM。

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