如何为生成的程序集创建一个 F# 类型提供程序?

9
我在使用F#生成类型提供程序时遇到问题,无法使用程序集中创建的任何类型。我制作了一个YouTube视频来演示这个问题。
错误信息如下:
  • 编译单元'Addressbook1'中的模块/命名空间“tutorial”未包含命名空间、模块或类型“Person”。
  • 在程序集“Addressbook1”中找到对类型“tutorial.Person”的引用,但在该程序集中找不到该类型。
我不明白为什么会出现这个问题,因为该类型明确存在于程序集中。针对此问题的故障排除方法就是检查程序集是否是一个非常基本的C# dll。视频中的代码可以通过git获得:
git url: https://code.google.com/p/froto/
git branch: help 如果您有任何故障排除的想法,将不胜感激。我希望能够在针对.proto文件的F#类型提供程序上取得更多进展,但现在我卡住了。

你是否考虑过使用F# 3示例包中提供的ProvidedTypes API(如此处所述:http://msdn.microsoft.com/en-us/library/hh361034.aspx),而不是使用原始类型提供程序API? - kvb
1个回答

5
我已经快速查看了您的代码 - 正如我在评论中提到的那样,我认为您最好使用由F# 3.0示例包定义并在MSDN上进行了一些文档记录的ProvidedTypes API。
基本上,原始类型提供程序API有很多假设内置其中,这些假设将很难手动维护。我认为您面临的特定问题是编译器希望在您的程序集中看到一个名为tutorial.Person的类型(因为它是您公开作为生成类型的tutorial.AddressbookProto上的方法的返回类型),但它从未嵌入到您的程序集中。
然而,这只是几个问题中的一个 - 正如您可能已经意识到的那样,如果您定义的类型不叫tutorial.AddressbookProto,则会看到其他错误。那是因为您正在使用具体类型作为ApplyStaticArguments的返回类型,但通常您会想要使用合成的System.Type实例,该实例准确反映用户使用的命名空间和类型名称(例如,在ProvidedTypes API中,ProvidedTypeDefinition类继承自System.Type并处理此类簿记)。

我一直在查看fsharpx的ProvidedTypes.fsi和ProvidedTypes.fs。我不理解的是为什么编译器无法找到tutorial.Person。它在GetGeneratedAssemblyContents(assembly)返回的程序集中。(https://github.com/fsharp/fsharpx/blob/master/src/FSharpx.TypeProviders/) - Cameron Taggart
你所描述的其他问题只是因为这是一个简单的测试案例。我正在返回一个具体类型,但如果你看一下主分支,你会发现我正在使用Roslyn在程序集中动态生成类型。我卡住的部分是F#找不到生成的程序集中的任何其他类型。 - Cameron Taggart
1
编译器只查看所提供命名空间返回的类型(如果必要,应用静态参数到这些类型中),以及其中嵌套的任何类型。这就是为什么它找不到Person类型的原因。 - kvb
那么,在这种简单的情况下,我如何为“教程”提供Person类型的教程呢?我认为我必须为“教程”创建一个新的IProvidedNamespace,然后从GetTypes()返回表示Person的Type。我会再仔细看看ProvidedTypes.fs。看起来ProvidedAssembly和ProvidedTypeDefinition可能能够在这里提供帮助。 - Cameron Taggart
@CameronTaggart - 我认为典型的模式是让您的类型提供程序返回一个容器类型,然后在其中嵌套AddressBook和Person。 - kvb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接