如果 .Net Core 可以在 Windows 上运行,为啥不能在 .Net Framework 中引用 .Net Core DLL?
Posted
技术标签:
【中文标题】如果 .Net Core 可以在 Windows 上运行,为啥不能在 .Net Framework 中引用 .Net Core DLL?【英文标题】:If .Net Core can run on Windows, why can't you reference a .Net Core DLL in .Net Framework?如果 .Net Core 可以在 Windows 上运行,为什么不能在 .Net Framework 中引用 .Net Core DLL? 【发布时间】:2018-11-05 04:33:08 【问题描述】:我明白为什么 .Net Framework 会导致 .Net Core、IE 出现问题,因为不存在特定于 Windows 平台的 API。但是为什么不能直接引用 .Net Core 作为 .Net Framework 中的库呢?如果 .Net Core 在 Windows 上运行,是什么阻止 .Net Framework 应用程序像使用库一样使用 .Net Core?
我知道您可以将 .Net Core 库移植到 .Net 标准库,但我的问题是为什么 .Net Framework 不能只引用用 .Net Core 编写的任何内容,因为它是跨平台的?
【问题讨论】:
.Net Framework 构建于 .Net Framework 4.7 或更低版本,但 .NetCore 更高。怎么跑? @FakeSaint:你应该做的是创建一个 .NET Standard 项目。您将能够从在 .NET Framework 和 .NET Core 上运行的应用程序中引用这个。这是两个独立的运行时。 是的,谢谢,我知道.Net Standard。我的困惑是为什么你不能只将 .net 核心类库作为依赖项包含在 .net 框架项目中 【参考方案1】:目前,不仅 .NET Framework 中的 API 在 .NET Core 中不可用(例如 Remoting、WCF 托管、其他应用程序域),而且现在 .NET Core 中也有在 .NET Core 中不可用的 API .NET Framework - 这包括对基类库的有用添加以及许多已添加到 .NET Core 2.1 中的基本 .NET 类型的基于 Span<T>
的 API。
要创建可在两个框架上使用的库,请使用 .NET Standard。
从技术上讲,.NET Framework 和 .NET Core 之间的最大区别在于(.dll 文件)框架实际承载其实现和类型定义的位置。
虽然 .NET Framework 在 mscorlib.dll
中有很多基本类型,但 .NET Core 可能会将它们包含在 System.Runtime.dll
或 System.Private.CoreLib.dll
中。
类型引用始终包括程序集的名称和命名空间+类型名称。如果您运行的框架在mscorlib
中定义了System.Object
,但应用程序引用了[System.Runtime]System.Object
,则可能无法加载。
.NET Core 2.0 已投入精力至少提供类型转发器,以便将引用重定向到正确的程序集。因此,在加载 .NET Framework 程序集时,.NET Framework 兼容性可能会将 [mscorlib]System.Object
重定向到 [System.Runtime]System.Object
。 (见Compatibility shim used by .NET Standard 2.0)
反之亦然。虽然较新版本的 .NET Framework 提供了许多 .NET Core 使用的相同程序集(通过类型转发实现),但它仅保证 .NET Standard 兼容性。如果您面向旧版本的 .NET Framework,则会将其他类型转发 DLL 添加到构建输出中以提供此兼容性(请参阅Why does my .NET Standard NuGet package trigger so many dependencies?)。
这可能会在一定程度上允许在 .NET Framework 上加载一些 .NET Core dll 文件,但不能保证它可以正常工作。如果 dll 使用 .NET Framework 上不可用的 API,它将失败,但当它引用具有不可用程序集名称的类型时,它也可能会失败。
请注意,这只适用于加载 dll 文件。项目到项目的引用将失败,因为该工具应禁止从 .NET Framework 项目中引用 .NET Core 项目。
【讨论】:
谢谢,非常感谢!但是,如果您在 .Net Framework 中引用 .net Core 库,为什么还需要类型转发呢?是什么阻止您包含整个 .net Core 运行时程序集,例如 System.Runtime 作为 .Net Framework 中的依赖项? 如果类型不能统一(例如,System.Object
的两个相互竞争的定义),则不可能进行类型交换。即使是程序集统一也很复杂,.NET Core 中的许多类型都依赖于在 .NET Framework CLR 上不起作用的本机资产或运行时 (CoreCLR) 功能。但我想这现在真的超出了范围,可能答案可能已经太详细了..
非常感谢您提供如此详尽的回答!给了我很多思考【参考方案2】:
跨平台与它无关。 .NET Core 和 .NET Framework 是完全不同且独立的框架。 .NET Standard 本质上是一个公开通用 API 的接口。 .NET Core 2.0+ 实现了 .NET Standard 2.0,以及它自己独特的 API。 .NET Framework 4.6.1+ 也实现了 .NET Standard 2.0,以及它自己独特的 API。从技术上讲,您只能引用面向 .NET Standard 或面向相同框架(.NET Core 到 .NET Core 和 .NET Framework 到 .NET Framework)的库。
然而,因为有这么多 .NET Framework 库,其中许多与 .NET Standard 完美兼容,但尚未更新为专门针对 .NET Standard,Microsoft 基本上在编译器中做了一个例外,以专门允许您可以在与 .NET Standard 2.0 兼容的东西(例如 .NET Core 2.0)中引用 .NET Framework 库。但是,当您这样做时,您会收到该库实际上可能不兼容的警告。例如,如果它使用 .NET Framework 独有的任何 API,那么在针对 .NET Core 时,您的应用程序将会崩溃。作为开发人员,您有责任测试并确保库兼容。
总之,您可以在 .NET Core 项目中引用 .NET Framework 库这一事实具有欺骗性。它基本上将 .NET Framework 库视为 .NET Standard 库,在大多数情况下都可以正常工作。但是,没有对其他方式进行特殊分配。
【讨论】:
谢谢!不过,我的具体困惑是为什么您不能只将 .Net 核心框架作为 .Net Framework 应用程序中的参考。这样,任何特定于 .net Core 的 API 都只会使用引用的 .net core 程序集。 因为框架没有随包一起提供。如果您的目标是 .NET Framework,那么它必须能够仅使用 .NET Framework 进行构建,而这对于 .NET Core 库是不可能的。 你可以多目标,但我不确定这是否真的有效。至少您可能不得不使用编译时指令,这很痛苦,而且不是一个很好的做法。 感谢您的帮助!【参考方案3】:兼容性: .NET Core 不支持所有功能和 最新版本的 .NET Framework 提供的功能。但 它可以用作 .NET Framework 的子集。此外,.NET Core 是 通过 .NET Standard 仍与 .NET Framework 兼容 库。因此,开发人员仍然可以运行应用程序 升级到 .NET Core 后使用 .NET Framework 开发。
在合并这两个框架之前请先检查一下:What's the difference between .NET Core, .NET Framework, and Xamarin?.NET Core, .NET Framework, Xamarin – The “WHAT and WHEN to use it”Difference between .Net Core and .Net Framework.NET Core vs .NET Framework: How to Pick a .NET Runtime for an Application
【讨论】:
以上是关于如果 .Net Core 可以在 Windows 上运行,为啥不能在 .Net Framework 中引用 .Net Core DLL?的主要内容,如果未能解决你的问题,请参考以下文章
如何把asp.net core的文件作为服务在windows下面部署
如何在 Windows 和 Linux 上正确存储 .NET Core 非交互式应用程序凭据?
无法解析远程名称 accountname.blob.core.windows.net
我可以在没有安装 Visual Studio 的情况下在 Windows 服务器上构建 .NET Core 应用程序吗?