当从非 F# 应用程序使用的 F# 中创建的 DLL 引用 Fsharp.Core v4.4.1.0 时,找不到文件



我的背景:我有一个在Visual Studio 2017中开发的DLL,它将从专有应用程序加载 - 这是我将数据以其专有格式导出到我正在构建的数据库的唯一方法。专有应用程序提供了一个包含其数据结构等的DLL,我已经能够将其添加为依赖项(但仅出于某种原因与.NET Framework 4.6.x一起使用,不适用于4.7.x)。发布者为此编写的代码示例都是 C# 编写的,但我可能更喜欢用 F# 编写插件,因为我沉迷于 Haskell,并且一直想学习 ML 方言。但是,我仍处于学习 C# 或 F# 的早期阶段。想想"经验丰富的基于Linux的程序员,他对整个Windows生态系统只有最基本的理解。

我的问题:我构建了这个DLL,从专有应用程序加载它,然后收到一个弹出窗口,报告以下错误:

Exception Type:FileNotFoundException
Details: could not load file or assembly 'FSharp.Core,
Version=4.4.1.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its 
dependencies. The system cannot find the file specified.

这似乎与Brent Tranberg的StackOverflow问题有着根本的不同,他至少能够加载依赖项;他们只是事后抱怨他。在这里,甚至没有加载依赖项。所以问题是(我认为)NuGet 包没有全局安装,也没有复制到构建输出中,因此专有应用程序永远不会知道它。到目前为止,我在网上发现的唯一有用的事情是告诉我,显然我正在尝试做的是一种反模式:F# 库显然只应该从 F# 应用程序中使用,这些应用程序可以定义它们绑定到哪个版本的 F# Core;它们永远不应该实际包含 F# Core 库本身。

一定误解了这里的东西,因为这对我来说听起来很疯狂。在 .NET 上,DLL 不仅仅是"我可以从 F# 应用程序调用的 F# 代码库":它们是多种不同语言可用于相互通信的核心互操作性构造。如何将此 F# 依赖项包含在一个不打算用于根本不了解 F#代码的应用程序的库中?

我是否应该违反之前指南的部分并"假设FSharp.Core在GAC中" - 如果是这样,我到底该如何开始这样做?(我被同一来源警告"VS2017不会将FSharp.Core安装到GAC"。或者,我的意思是,由于动态链接不起作用,有没有一种很好的方法来静态链接此代码?有没有办法将 NuGetPackageReference转换为Reference,以便我可以添加<Private>true</Private>,以便将其包含在 DLL 文件夹中?我还有哪些其他选择?

(此后我尝试了后者,它实际上并没有将所需的DLL复制到构建文件夹中。我也尝试直接将Fsharp.Core DLL添加为"依赖项" - 仍然没有骰子。如果我每次构建时都复制它,它确实有效,但这似乎是解决Visual Studio不可能遇到的更深层次问题的一种非常脆弱的方法。

(警告:自我回答,解决方法)

更多的谷歌搜索最终导致了一个非常切线的线程,即NuGet对.NET Core的版本感到困惑,否则这将没有帮助,除了主要开发人员之一(Kevin Ransom)说对FSharp.Core的引用被隐式包含,因为"大多数项目不需要显式引用FSharp.Core"。我想从 C# 使用的 F# 库不是"大多数",但如果根本不支持它,我感到非常惊讶。但是,他对想要明确引用它的人有一个建议,这对我有用,可以解决此问题。

所以我的解决方法如下所示:

  • 关闭 Visual Studio 2017。
  • 在单独的文本编辑器中打开<ProjectName>.fsproj
  • 在前导<PropertyGroup>添加凯文·兰塞姆的建议,<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>.
  • 追踪到FSharp.Core.dll的相对路径;在我的例子中,它是在.........nugetpackagesfsharp.core4.2.3libnet45FSharp.Core.dll
  • 将其作为持有PrivateReferenceItemGroup添加到项目中(这与PropertyGroup并行)。因此,对我来说,该参考如下所示:

    <ItemGroup>
    <Reference Include="FSharp.Core">
    <HintPath>.........nugetpackagesfsharp.core4.2.3libnet45FSharp.Core.dll</HintPath>
    <Private>true</Private>
    </Reference>
    </ItemGroup>
    

    我不需要删除 NuGet Core 添加的<PackageReference>

  • 保存该文件,在 Visual Studio 2017 中重新打开解决方案,然后重新生成。
  • 然后FSharp.Core.dll神奇地出现在我的构建文件夹中,其中包含我自己的.dll文件。

如果这是一个糟糕的解决方法,请在评论中告诉我!我对这一切真的很陌生,在"该死的VS已经把这个愚蠢的文件放在那个愚蠢的目录中!"的机智结束阶段,所以如果上面的步骤有点绝望,那就是原因。

相关内容

最新更新