来自 F# XmlProvider 的类型检查错误 FS3033

8
我一直在使用FSharp.Data的XmlProvider生成与XML片段对应的类型,并将其存储在F#项目源目录中的文件中。我通过文件路径对XmlProvider进行参数化,然后将此代码编译为DLL。如果我从无法读取源目录的另一个F#项目引用此程序集的已编译DLL,则在该项目的编译时会出现错误FS3033“无法从'config_schema.xml'读取示例XML:找不到(路径)”。这是为什么呢?我的理解是,在编译之后,对应于XML样本的类型是标准的成熟类型,并且应该出现在编译的DLL中。为什么类型的使用者(第二个项目中的代码)仍然需要引用样本才能编译?
1个回答

9
这很微妙。当您编译使用擦除类型提供程序(如XmlProviderJsonProvider)的代码为DLL时,编译器实际上不会存储生成的类型。这意味着当您从另一个库引用DLL时,编译器将再次触发类型提供程序——即使最终用户代码(您的库的用户)实际上并未使用类型提供程序。
这意味着即使在您编译并将库分发给用户后,类型提供程序仍然需要能够访问样例。
您可以使用相对路径并将示例与库一起复制,但这不是非常优雅。我们在F# Data Toolbox中也存在完全相同的问题,该库使用JsonProvider进行操作。
F# Data有一个特殊选项来解决这个问题。您可以在编译DLL时将示例作为资源嵌入 - 这样,类型提供程序将首先查找嵌入式资源(在您分发库后起作用),如果没有找到,则会查找本地文件(在编译库时需要)。
请参阅此处F# Data Toolbox的实现
type Response = JsonProvider<"json/bearer_token.json", 
  EmbeddedResource="FSharp.Data.Toolbox.Twitter,bearer_token.json">

嵌入式资源被设置在项目文件中:(参见链接)
<EmbeddedResource Include="json/bearer_token.json">
  <Link>json/bearer_token.json</Link>
</EmbeddedResource>

我认为这对JSON和XML提供程序都是支持的。

1
生成的类型未被使用并再次触发提供程序的原因是什么?这种行为在 F# 的未来版本中可能会发生变化吗? - Nikon the Third

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