简体   繁体   English

来自F#XmlProvider的Typecheck错误FS3033

[英]Typecheck error FS3033 from F# XmlProvider

I've been using the XmlProvider from FSharp.Data to generate types corresponding to a fragment of XML which I am storing in a file in the source directory of the F# project being built. 我一直在使用FSharp.Data中的XmlProvider来生成与XML片段相对应的类型,我将其存储在正在构建的F#项目的源目录中的文件中。

I parameterize the XmlProvider with the path of the file. 我用文件的路径参数化XmlProvider。 This code is then compiled into a DLL. 然后将此代码编译为DLL。

If I then reference the compiled DLL of this assembly from another F# project which is unable to read from the source directory then, at compile time for that project I get the error FS3033 'Cannot read sample XML from 'config_schema.xml': Could not find (path)'. 如果我从另一个无法从源目录中读取的F#项目引用此程序集的已编译DLL,那么在该项目的编译时我得到错误FS3033'无法从'config_schema.xml'读取示例XML:不能找到(路径)'。

Why is this? 为什么是这样? My understanding was that after compilation, the type corresponding to the XML sample was a standard fully fledged type and this is what should end up in the compiled DLL. 我的理解是,在编译之后,与XML样本对应的类型是标准的完全成熟类型,这应该是编译后的DLL中的结果。 Why does a consumer of the type (code in the second project) still need to reference the sample to compile? 为什么类型的消费者(第二个项目中的代码)仍然需要引用样本进行编译?

This is subtle. 这很微妙。 When you compile code that uses a erasing type provider like XmlProvider or JsonProvider into a DLL, the compiler does not actually store the generated types. 当您将使用XmlProviderJsonProvider等擦除类型提供程序的代码编译到DLL中时,编译器实际上并不存储生成的类型。 This means that when you reference the DLL from another library, the compiler will trigger the type provider again - even though the end-user code (user of your library) is not actually using the type provider. 这意味着当您从另一个库引用DLL时,编译器将再次触发类型提供程序 - 即使最终用户代码(库的用户)实际上并未使用类型提供程序。

This means that the type provider needs to be able to access the sample, even after you compiled the library and distributed it to your users. 这意味着类型提供程序需要能够访问示例,即使在编译库并将其分发给用户之后也是如此。

You could use relative paths and copy the samples with your library, but that's not very elegant. 您可以使用相对路径并将样本与库一起复制,但这不是很优雅。 We actually have exactly the same problem in F# Data Toolbox which is a library that uses JsonProvider under the cover. 我们实际上在F#Data Toolbox中有完全相同的问题,这是一个在封面下使用JsonProvider的库。

F# Data has a special option for this purpose. F#Data有一个特殊选项用于此目的。 You can embed the sample as a resource when compiling the DLL - that way, the type provider will first look for an embedded resource (which works after you distributed your library) and if it's not there, it will look for a local file (which you need when compiling the library). 您可以在编译DLL时将示例作为资源嵌入 - 这样,类型提供程序将首先查找嵌入式资源(在您分发库之后可以正常工作),如果它不存在,它将查找本地文件(你需要在编译库时)。

See how this is done in F# Data Toolbox here : 在此处查看如何在F#Data Toolbox中完成此操作

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

The embedded resource is set in the project file : 嵌入资源在项目文件中设置:

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

I believe this is supported for both JSON and XML providers. 我相信JSON和XML提供程序都支持这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM