在F#Interactive中加载dotnet项目文件

时间:2018-08-09 16:25:37

标签: .net f#

我有一个F#dotnet项目,该项目在我的.fsproj中有一些依赖性(例如<PackageReference Include="FSharp.Data" Version="3.0.0-beta4" />)。

现在,我想在编写的模块中测试某些功能,因此我开始fsharpi并尝试用#load "Program.fs";;加载模块。

但是,我得到error FS0039: The type 'CsvProvider' is not defined

如何为模块加载正确的依赖项?

我看到了一些变通方法,其中包括从一些晦涩的系统相关路径(例如#load a package in F# interactive (FSharpChart.fsx))中手动加载所有必需的dll,但是我想必须有更好的方法来做到这一点。

3 个答案:

答案 0 :(得分:2)

为了访问导入库中的代码,您需要告诉FSI加载它们。

在最低级别上,可以使用#r指令来完成此操作:

#r "./packages/FSharp.Data/lib/whatever/FSharp.Data.dll"

这通常足以一次性完成。

但是,如果有很多引用,您的IDE通常可以自动为您执行此操作。例如,在Visual Studio中,您可以右键单击该项目,然后选择“将引用发送到F#Interactive”或“使用引用生成脚本文件”(不确定确切的用词)。如果安装了Ionide扩展名,则VSCode中提供相同的选项。

此外,还有一个有效的提案+原型可以直接在FSI中支持软件包-参见https://github.com/fsharp/fslang-suggestions/issues/542。但是,它尚未合并,似乎已停滞了一点。

答案 1 :(得分:1)

有几个选项可以做到这一点,但没有一个是完美的。

离子

如果您使用的是 Ionide,那么您可以在 F# 视图中右键单击项目并选择“为 FSI 生成引用”。这将创建一个 F# 脚本,为您加载所有依赖项和项目文件。在下面写下您的测试代码。

这种方法的缺点:

  • 每次项目文件或依赖项更改时,您都需要运行该过程。
  • 不适用于您无法访问 VS Code 的情况

如果您使用的是 Paket,那么您可以为您的项目生成“加载脚本”:

dotnet paket generate-load-scripts

这将在 ./paket/load 中生成 F# 脚本。每个依赖项(及其传递依赖项)和每个包“组”都有一个加载脚本。

如果您添加以下行,这会自动与您的 paket.dependencies 同步:

generate_load_scripts: true

见:https://fsprojects.github.io/Paket/paket-generate-load-scripts.html

这种方法的缺点:

  • 它可能会加载比您实际需要更多的依赖项,这会降低性能
  • 您必须#load手动投影文件

Dotnet + Nuget

.NET 5 的新功能,您可以直接在 fsx 文件中编写 Nuget 字符串。这是快速脚本的一个很棒的功能!

#r "nuget: FParsec"

// Package with a specific version
// #r "nuget: FParsec,1.1.1"

open FParsec

#load "./Types.fs"

// etc...

这种方法的缺点:

  • 它不会与 Paket 同步包版本,如果您在项目代码中使用它
  • 您必须#load手动投影文件

有一天?

在理想的世界中,我们可以这样做:

#r "fsproj: ./my-proj.fsproj"

open FParsec

// etc...

这里有一个问题:https://github.com/dotnet/fsharp/issues/8764

答案 2 :(得分:0)

根据对Fyodor答案的评论中的要求,这是我过去用来生成在F#Interactive中加载 ERROR 7732 --- [ XNIO-2 task-1] p.d.dealer.aop.logging.LoggingAspect : Exception in pl.ddweb.dealer.web.rest.CarResource.getAllCars() with cause = 'java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: make of: pl.ddweb.dealer.domain.Image [select new pl.ddweb.dealer.web.rest.dto.ImageDTO(image.id, image.thumbnail, image.isMain, image.imgContentType, image.car) from pl.ddweb.dealer.domain.Image image WHERE (image.car.received =:received) order by image.make asc, image.id asc]' and exception = 'org.hibernate.QueryException: could not resolve property: make of: pl.ddweb.dealer.domain.Image [select new pl.ddweb.dealer.web.rest.dto.ImageDTO(image.id, image.thumbnail, image.isMain, image.imgContentType, image.car) from pl.ddweb.dealer.domain.Image image WHERE (image.car.received =:received) order by image.make asc, image.id asc]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: make of: pl.ddweb.dealer.domain.Image [select new pl.ddweb.dealer.web.rest.dto.ImageDTO(image.id, image.thumbnail, image.isMain, image.imgContentType, image.car) from pl.ddweb.dealer.domain.Image image WHERE (image.car.received =:received) order by image.make asc, image.id asc]' org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.QueryException: could not resolve property: make of: pl.ddweb.dealer.domain.Image [select new pl.ddweb.dealer.web.rest.dto.ImageDTO(image.id, image.thumbnail, image.isMain, image.imgContentType, image.car) from pl.ddweb.dealer.domain.Image image WHERE (image.car.received =:received) order by image.make asc, image.id asc]; nested exception is java.lang.IllegalArgumentException: org.hibernate.QueryException: could not resolve property: make of: pl.ddweb.dealer.domain.Image [select new pl.ddweb.dealer.web.rest.dto.ImageDTO(image.id, image.thumbnail, image.isMain, image.imgContentType, image.car) from pl.ddweb.dealer.domain.Image image WHERE (image.car.received =:received) order by image.make asc, image.id asc] 所需的#r#load指令的脚本:

.fsproj

我不确定这是否完全完美,例如,我认为它的依赖项排序不正确。但是,如果要增强它,应该是一个合理的起点。