我一直在使用来自FSharp.Data的XmlProvider来生成与XML片段相对应的类型,该片段存储在正在构建的F#项目的源目录中的文件中。
我用文件的路径参数化XmlProvider。然后将此代码编译为DLL。
如果我然后从另一个无法从源目录读取的F#项目中引用了该程序集的已编译DLL,则在该项目的编译时,我会收到错误消息
FS3033'无法从'config_schema.xml'中读取示例XML:找不到(路径)'。
为什么是这样?我的理解是,在编译之后,与XML示例相对应的类型是标准的完全成熟的类型,而这正是最终在编译后的DLL中所需要的类型。
为什么类型(第二个项目中的代码)的使用者仍然需要引用示例进行编译?
最佳答案
这是微妙的。当您将使用诸如XmlProvider
或JsonProvider
的擦除类型提供程序的代码编译到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提供程序都支持此功能。