为什么我的 .NET Standard NuGet 包会触发如此多的依赖项?

2024-03-25

我一直在闲逛.NET 标准项目 https://github.com/tdwright/contabs和 NuGet。我有一个工作项目并且有已将其上传到 NuGet.org https://www.nuget.org/packages/ConTabs.tdwright/0.1.0。我的项目面向 .NET Standard 1.3,其中应该支持 https://learn.microsoft.com/en-us/dotnet/standard/net-standard.NET Framework 4.6 和 .NET Core 1.0。

但是,当我尝试将我的项目(通过 NuGet)添加到新的 .NET Framework 4.6 项目时,依赖关系解析为47包!它们都是系统库,并且似乎是 Microsoft.NETCore.Platforms 或 NETStandard.Library 1.6.1 的依赖项。 (完整 PM 输出的要点。 https://gist.github.com/tdwright/0b3568a9da2e318fe6e3c2efc40fcff4)

我的项目仅导入(using)一些库,其中没有一个是我手动添加的;即它们都是“附带”.NET Standard 的库。这些库是:

  1. System
  2. 系统.文本
  3. 系统.反射
  4. 系统Linq
  5. 系统.集合.通用;

问题是,我决定让我的项目以 .NET Standard 为目标,因为我希望它能够跨 .NET Framework 和 .NET Core 应用程序无缝工作。我认为标准的全部要点是设置最低级别的兼容性。通过扩展,我想我假设(可能是错误的)像 System.Console 这样的库将在 Core 或 Framework 中自动可用。

当我将我的标准项目作为同一解决方案中的框架和核心项目的依赖项进行测试时,我没有注意到类似的情况,因此我怀疑这可能是 NuGet 的事情。

这里究竟发生了什么?如何在没有大量依赖项的情况下使我的 .NET Standard 库在 NuGet 上可用?

我指定 NuGet 包的方式有问题吗?或者我从根本上误解了什么?


你没有做错任何事,这是预料之中的事情。如果您只想将自己的 DLL 添加到新的 .NET Framework 项目中,那么您的库必须以 .NET Standard 2.0 为目标,等待本机支持 API 和程序集版本的 .NET Framework 版本 - 这将是更新为 4.7.2(虽然 .NET Framework 4.7.1 支持所有 API,但某些程序集的版本控制方式存在错误,因此工具 (VS 2017 15.5+) 将添加其他程序集来修复该问题)。

您所看到的是 .NET Standard 的构建方式以及对受支持框架的支持的实现方式的副作用。根据您的目标 .NET Standard 版本以及用于引用库包的工具,这也有所不同。

在 .NET Standard NETStandard.Library元包又引用了额外的(System.*) 包。这些包包含构成“.NET 标准合约”的参考程序集 - 一组 API 和程序集名称 + 版本。

当应用程序引用为 .NET Standard 1.0-1.6 创建的 NuGet 包时,这些单独的包不会引入引用程序集,而是引入应用程序目标框架的实现程序集。

对于 .NET Core,这些与已经属于运行时一部分的程序集相匹配,因此 DLL 文件不会最终出现在构建的应用程序旁边。然而,当针对 .NET Core 1.1 发布一组新的包时,情况发生了变化(NETStandard.Library版本 1.6.1)。这导致为 .NET Core 1.0 构建的应用程序最终获得了本应包含在 .NET Core 1.1 中的更新的实现程序集(幸运的是,1.1 随后成为“长期支持”版本,因为这引发了关于哪些程序集的讨论)是 LTS 承诺的一部分)。

在 .NET Framework 上,这些库(有一些例外,例如System.Net.Http)不做太多事情 - 他们只是转发到系统程序集。例如,“合同”定义了System.Object被定义在一个System.Runtime.dll集会。所以System.Runtime.dll您最终在 .NET Framework 应用程序中得到的文件包含System.Runtime.dll包含转发到 .NET Framework 的类型mscorlib.dll。 .NET Core 已经包含了不同的System.Runtime.dll这对该平台做了一些不同的事情。此机制允许单个 DLL 文件在两个平台上工作,因为这些类型转发和附加实现确保在两个实现上工作的相同“契约”(类型 + 程序集 + 程序集版本)。

.NET Standard 2.0 旨在减少必要的包和 DLL 的数量,并消除对NETStandard.Library每当发布新的 .NET Core 版本时。

因此,对于 .NET Standard 2.0 和 .NET Core 2.0,NETStandard.Librarypackage 仅将用于编译代码的参考程序集引入项目,但生成的 NuGet 包不再依赖于此包。因此,当您创建面向 .NET Standard 2.0 的库并发布它时,它将没有 NuGet 依赖项(除非您添加其他依赖项)。

使用 .NET Standard 库时引入的“支持库”的逻辑已移至构建期间使用的工具中。因此,当一个库包含对netstandard.dll添加到 .NET Framework 项目后,该工具将根据所使用的 .NET Framework 版本添加必要的支持 DLL。这是针对 .NET Standard 2.0 以及 .NET Standard 1.5+ 完成的,因为 .NET Framework 4.6.1 通过这些类型的 DLL 文件追溯地与 .NET Standard 2.0(之前为 1.4)兼容。相同的工具还确保即使 NuGet 包以某种方式引入到此类应用程序项目中,通过 NuGet 引入的任何 .NET Standard 实现库也会从构建中删除。因此,如果您引用在 .NET Core 1.0 发布时构建的 .NET Standard 1.0 NuGet 包,则其所有 NuGet 依赖项都会被删除,您将获得构建工具附带的支持库。

这个想法是 .NET Framework 4.7.1 将包含所有必要的程序集“收件箱”,以便netstandard.dll, System.Runtime.dll等是 .NET Framework 的一部分,任何 .NET Standard 1.0-2.0 DLL 文件都会“正常工作”,问题是这些“收件箱”DLL 文件对于某些程序集来说版本号太低,因此库将无法加载 -通过再次更改工具以包含具有更高版本号的 DLL 文件作为支持库,这些文件又转发到“收件箱”.NET Framework 程序集,解决了此问题。计划在 .NET Framework 4.7.2 中修复此问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我的 .NET Standard NuGet 包会触发如此多的依赖项? 的相关文章

  • Lightspeed 与 NHibernate

    有什么体验光速 http www mindscape co nz products LightSpeed comparison aspx Mindscape 提供的比较并没有过多说明 NHibernate Lightspeed 看起来很灵活
  • 点击浏览器后退按钮时如何刷新 ASP .NET MVC 页面

    我刚刚发现 当我单击任何 ASP NET MVC 页面上的浏览器后退按钮时 没有任何反应 并且页面不会更新 并且只有当您单击 F5 时才会更新 主要问题是我对页面的 DOM 进行了一些更改 即添加表格行 选择单选按钮等 当我通过点击浏览器后
  • 无法启动 Windows 服务,错误 1064

    我编写了一个在 Win10 上运行的 Windows 服务 它运行得非常好 直到我决定对其进行一些更改 我重写了一些逻辑 在调试和发布配置中进行了测试 一切都很好 然后 我使用卸载了当前版本的服务installutil exe u serv
  • Python tkinter.filedialog Askfolder 干扰 clr

    我主要在 Spyder 中工作 构建需要弹出文件夹或文件浏览窗口的脚本 下面的代码在spyder中完美运行 在 Pycharm 中 askopenfilename工作良好 同时askdirectory什么都不做 卡住了 但是 如果在调试模式
  • 如果.Net Core可以在Windows上运行,为什么不能在.Net Framework中引用.Net Core DLL?

    我明白为什么 Net Framework 可能会在 Net Core IE 中导致问题 因为不存在特定于 Windows 平台的 API 但是为什么不能直接引用 Net Core 作为 Net Framework 中的库呢 如果 Net C
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 在 C# 中将位从 ulong 复制到 long

    所以看来 NET 性能计数器类型 http msdn microsoft com en us library system diagnostics performancecounter aspx有一个恼人的问题 它暴露了long对于计数器
  • 从 Orchard 内的主题渲染图像

    我刚刚选择 Orchard 来构建我的博客 作为创建这个新博客的努力的一部分 我正在创建一个自定义主题 这个自定义主题同时具有 CSS 和图像 我的问题 我的问题基本上可以归结为 如何渲染属于主题一部分的图像 到目前为止我已经尝试过的 我尝
  • 根据 VS2008 中的构建配置排除整个文件

    我的项目有三种不同的配置 这三种配置不需要将所有文件构建到应用程序中 实际上 我更希望能够从构建中排除这些文件 这将使我的应用程序更加轻量级 我正在寻找的是 if MYCONFIG or if DEBUG声明但用于文件 我已经读到这可以通过
  • 通过本地项目引用导入 NuGet 引用

    假设我有一个 主 C 项目 它使用 NuGet 来管理其第三方依赖项 现在假设我在主项目旁边创建一个单元测试项目 其中包含主项目作为参考 不幸的是 我似乎需要重新添加通过主项目中的 nuget 包含的依赖项 以便使用它们为单元测试项目中的单
  • 添加 LINQ 的 LongCount 扩展方法是否有实际原因?

    LINQ 有 2 种计算可枚举数的方法 Count and LongCount 实际上 这两者之间的唯一区别是第一个返回一个int 而第二个返回一个long 我不清楚为什么添加第二种方法 它的唯一用例似乎是处理超过 2B 元素的枚举 对我来
  • 我可以将 SimpleInjectors 诊断结果写入日志文件吗?

    在调用中使用简单注入器container Verify 在我的配置结束时 并在调试器中获取诊断信息 如中所述文档 http simpleinjector codeplex com wikipage title Diagnostics 我想将
  • 如何检查 FTP 目录是否存在

    寻找通过 FTP 检查给定目录的最佳方法 目前我有以下代码 private bool FtpDirectoryExists string directory string username string password try var r
  • 限制对记录的访问。基于声明的权限是个好主意吗

    在 net 基于声明的身份框架中 如果我想限制用户对某个帐户 特定帐户 123456 执行操作 查看或编辑 我说的是商业实体 例如银行帐户 创建索赔是个好主意吗对于他们可以查看或编辑的每个帐户 一组中有很多索赔有什么缺点吗 系统管理员可能有
  • 捕获特定的 WebException (550)

    假设我创建并执行一个System Net FtpWebRequest 我可以用catch WebException ex 捕获此请求引发的任何与 Web 相关的异常 但是 如果我有一些逻辑只想在由于以下原因引发异常时执行 550 file
  • MonoState、Singleton 或派生形式:CRUD 应用程序的最佳方法?

    我有一个相当大的 CRUD WinForm 应用程序 其中有许多对象 人员 注册 计划 案例注释等 该应用程序由 30 多种表单组成 UI 逻辑上被分解 会员 注册 计划 案例说明等 我正在尝试弄清楚如何创建我的人物对象搜索后搜索表格并将对
  • xamarin studio 中有包管理器控制台吗

    我正在使用 xamarin studio 带有 nuget 包管理插件 并且在我的项目中有一些 nuget 包 项目上下文菜单中有 管理 和 恢复 nuget 包 但也有控制台吗 Xamarin Studio 和 MonoDevelop 的
  • 删除 TableLayoutPanel 中的特定行

    我有 TableLayoutPanel 我以编程方式添加行 用户基本上选择一个属性 然后与一些控件一起显示在表中 我想我在这里有一个一般性的理解问题 我会尽力解释它 每行中的控件之一是 删除 按钮 该按钮应该删除它所在的行 我所做的是将事件
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 有没有办法禁用 .NET 标签的“双击复制”功能?

    这真的很烦人 我使用标签作为列表项用户控件的一部分 用户可以单击它来选择列表项 然后双击它来重命名它 但是 如果剪贴板中有名称 双击标签会将其替换为标签文本 我还检查了应用程序中的其他标签 双击它们也会将其复制到剪贴板 我没有在这个程序中编

随机推荐