来自F#XmlProvider的Typecheck错误FS3033

时间:2014-08-06 09:13:34

标签: xml types f# type-providers f#-data

我一直在使用FSharp.Data中的XmlProvider来生成与XML片段相对应的类型,我将其存储在正在构建的F#项目的源目录中的文件中。

我使用文件路径参数化XmlProvider。然后将此代码编译为DLL。

如果我从另一个无法从源目录中读取的F#项目引用此程序集的已编译DLL,那么在该项目的编译时我得到错误 FS3033'无法从'config_schema.xml'读取样本XML:找不到(路径)'。

这是为什么?我的理解是,在编译之后,与XML样本对应的类型是标准的完全成熟类型,这应该是编译后的DLL中的结果。 为什么类型的使用者(第二个项目中的代码)仍然需要引用要编译的样本?

1 个答案:

答案 0 :(得分:8)

这很微妙。当您将使用删除类型提供程序(如XmlProviderJsonProvider的代码编译到DLL中时,编译器实际上并不存储生成的类型。这意味着当您从另一个库引用DLL时,编译器将再次触发类型提供程序 - 即使最终用户代码(库的用户)实际上并未使用类型提供程序。

这意味着类型提供程序需要能够访问示例,即使在编译库并将其分发给用户之后也是如此。

您可以使用相对路径并将样本与库一起复制,但这不是很优雅。我们实际上在F# Data Toolbox中存在完全相同的问题,这是一个在封面下使用JsonProvider的库。

F#Data为此提供了一个特殊选项。您可以在编译DLL时将示例作为资源嵌入 - 这样,类型提供程序将首先查找嵌入式资源(在您分发库之后可以正常工作),如果它不存在,它将查找本地文件(你需要在编译库时)。

了解这是如何完成的in F# Data Toolbox here

type Response = JsonProvider<"json/bearer_token.json", 
  EmbeddedResource="FSharp.Data.Toolbox.Twitter,bearer_token.json">

嵌入资源设置为in the project file

<EmbeddedResource Include="json/bearer_token.json">
  <Link>json/bearer_token.json</Link>
</EmbeddedResource>

我相信JSON和XML提供商都支持此功能。