【问题标题】:How do I create an F# Type Provider for a generated assembly?如何为生成的程序集创建 F# 类型提供程序?
【发布时间】:2013-01-11 18:07:27
【问题描述】:

我在为 F# 生成类型提供程序使用在程序集中创建的任何类型时遇到问题。我创建了一个 YouTube video 来演示这一点。

我得到的错误信息是:

  • 编译单元“Addressbook1”中的模块/命名空间“教程”不包含命名空间、模块或类型“Person”
  • 在程序集“Addressbook1”中找到对类型“tutorial.Person”的引用,但在该程序集中找不到该类型

我不明白,因为类型肯定在程序集中。为了解决这个问题,程序集是一个非常基本的 C# dll。视频中的代码可通过 git 获取:

git 网址:https://code.google.com/p/froto/
git 分支:帮助

任何故障排除想法将不胜感激。我希望在 an F# Type Provider for .proto files 上取得更多进展,但我坚持这一点。

【问题讨论】:

  • 您是否考虑过使用 F# 3 示例包中的 ProvidedTypes API(如 here 所述)而不是使用原始类型提供程序 API?

标签: f# type-providers


【解决方案1】:

我快速浏览了您的代码 - 正如我在评论中提到的,我认为使用由 F# 3.0 示例包定义并在 MSDN 上记录(有点)的 ProvidedTypes API 会更好地为您服务.

基本上,原始类型提供程序 API 包含很多假设,您很难手动维护这些假设。我认为您遇到的具体问题是编译器希望在您的程序集中看到一个名为 tutorial.Person 的类型(因为它是 tutorial.AddressbookProto 上的方法的返回类型,您将其公开为生成的类型),但它从未嵌入到您的程序集中。

但是,这实际上只是几个问题之一 - 正如您可能已经意识到的那样,如果您定义的类型被称为 tutorial.AddressbookProto 以外的任何名称,您将看到额外的错误。这是因为您使用具体类型作为 ApplyStaticArguments 的返回值,但您通常希望使用合成的 System.Type 实例,该实例准确反映用户使用的命名空间和类型名称(例如,在 ProvidedTypes API 中,@ 987654327@ 类继承自 System.Type 并处理此簿记)。

【讨论】:

  • 我一直在看 fsharpx 的 ProvidedTypes.fsi 和 ProvidedTypes.fs。我不明白的是为什么编译器找不到tutorial.Person。它位于从 GetGeneratedAssemblyContents(assembly) 返回的程序集中。 (github.com/fsharp/fsharpx/blob/master/src/FSharpx.TypeProviders)
  • 您描述的其他问题仅仅是因为它是一个简单的测试用例。我正在返回一个具体类型,但如果您查看 master 分支,您会发现我正在使用 Roslyn 动态生成程序集中的类型。我坚持的部分是 F# 没有从生成的程序集中找到任何其他类型。
  • 编译器只查看提供的命名空间返回的类型(如果需要,将静态参数应用于这些类型),以及嵌套在其中的任何类型。这就是它找不到 Person 类型的原因。
  • 那么,在这个简单的案例中,如何提供tutorial.Person类型呢?我相信我必须为“tutorial”创建一个新的 IProvidedNamespace,然后从 GetTypes() 返回一个表示 Person 的 Type。我会再看一下 ProvidedTypes.fs。看起来 ProvidedAssembly 和 ProvidedTypeDefinition 可能会在这里提供帮助。
  • @CameronTaggart - 我认为典型的模式是让您的类型提供程序返回的类型是容器类型,然后将 AddressBook 和 Person 嵌套在它下面。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
相关资源
最近更新 更多