简体   繁体   English

如何编写强制复杂模式的F#类型提供程序?

[英]How to approach writing an F# type provider that enforces complex schema?

Just recently I worked with some data for traffic and travel information, that is data in Datex2 format. 就在最近,我处理了一些流量和旅行信息数据,即Datex2格式的数据。 The project wasn't long and is over now, and I went on as usually and generated a bunch of strongly typed C# classes with xsd.exe tool, did some serializing, light processing and so forth. 该项目时间不长,现在已经结束了,我继续像往常一样 ,使用xsd.exe工具生成了一堆强类型的C#类,进行了一些序列化,光处理等等。 However, now in hindsight I became to wonder if this would have been a good case for an F# type provider and so to take my first stab on this subject. 然而,现在事后回想起来,我开始怀疑这对于F#类型的提供商来说是否是一个好例子,所以我第一次尝试这个问题。

With this in mind, how should one approach a situation where there's a complex schema that shouldn't change often? 考虑到这一点,如何处理一个不应经常改变的复杂模式的情况? As there isn't a publicly available type provider that would infer types from a schema directly, I guess the options are to: 由于没有可直接从模式推断类型的公开类型提供程序,我猜选项是:

  • Use the XML type provider . 使用XML类型提供程序
  • Generate the types with and external tool, xsd.exe in this case -- taking a cue from the WSDL type provider (which uses svcutil.exe ). 在这种情况下使用和外部工具xsd.exe生成类型 - 从WSDL类型提供程序 (使用svcutil.exe )获取提示。
  • Roll the types by hand (possibly modifying the output of xsd.exe ). 手动滚动类型(可能修改xsd.exe的输出)。
  • Generate the types (as in previous bullet)/use the XML Type provider and do constant serializing, deserializing and schema validation in the background. 生成类型(如前面的项目符号)/使用XML Type提供程序并在后台进行常量序列化,反序列化和模式验证。

Then I also started to wonder about the C#-F# story (eg generated or erased types) and what if I wanted to modify the types to better check constraints like <xs:element name="ilc" type="D2LogicalModel:TpegIlcPointDescriptor" maxOccurs="3"> in the schema whilst also providing a good developer experience. 然后我也开始怀疑C#-F#故事(例如生成或擦除类型)以及如果我想修改类型以更好地检查约束,如<xs:element name="ilc" type="D2LogicalModel:TpegIlcPointDescriptor" maxOccurs="3">在架构中<xs:element name="ilc" type="D2LogicalModel:TpegIlcPointDescriptor" maxOccurs="3">同时还提供良好的开发人员体验。

Rolling one's own types looks like a rather laborius endavour and the the two last points seemed being the most appealing ones, so taking the route as described here by nos in another SO post. 滚动一个自己的类型看起来像一个相当laborius endavour和最后两个点似乎是最有吸引力的,所以服用的路线描述这里在另一个SO发布。 I used System.Xml and System.CodeDom and modified the code to use Microsoft.FSharp.Compiler.CodeDom and FSharpCodeProvider to generate the F# types. 我使用System.XmlSystem.CodeDom并修改代码以使用Microsoft.FSharp.Compiler.CodeDomFSharpCodeProvider生成F#类型。

Alas! 唉! The generated F# code doesn't compile (even after adding the appropriate referecenses etc.) At this point I thought I could ask some directions. 生成的F#代码无法编译(即使添加了适当的引用等)。此时我想我可以问一些方向。

Question: Is there a recommened, experience backed way to create a type provider to conform to a somewhat complex XML schema (taking Datex2 as a case example) if I would like to enforce constraints as described in a given schema as early as possible in the development cycle? 问题:是否有一种建议的,经验支持的方法来创建类型提供程序以符合稍微复杂的XML模式(以Datex2为例)如果我想尽可能早地在给定模式中强制执行约束发展周期?

<edit 2013-12-10: Rune FS is attempting to take a stab on this, see his SO question Getting compile error on provided type . <edit 2013-12-10: Rune FS正试图对此进行攻击,请参阅他提出的问题在提供的类型上获取编译错误

This is a pretty complex question and I guess there is no simple answer - I think you probably enumerated all the options and also most of their trade-offs. 这是一个非常复杂的问题,我想没有简单的答案 - 我想你可能列举了所有选项以及他们的大部分权衡。 For one-off projects, it does not really make sense to build a specific type provider for just a single purpose, so I think using XML provider or code generation are the only choices. 对于一次性项目,仅为一个目的构建特定类型提供程序没有任何意义,因此我认为使用XML提供程序或代码生成是唯一的选择。 Code generation (when modifying the generated code) is a maintenance nightmare. 代码生成(修改生成的代码时)是维护的噩梦。

As for the XML type provider, we have a work item to add support for XSD (this would be nice community contribution as it is quite stand-alone), so if we had that, then I believe using the XML type provider would be perfect, because you could just pass it the DATEX II schema. 至于XML类型提供程序,我们有一个工作项来添加对XSD的支持(这将是很好的社区贡献,因为它非常独立),所以如果我们有,那么我相信使用XML类型提供程序将是完美的,因为你可以把它传递给DATEX II架构。

At the moment, F# Data uses erased types (bad for C# interop) but we are actually considering switching to generated types, which would make the provider usable from C# (via small F# project) - so, I think the type providers are the answer here, but they might need a few improvements before they're perfect for your project (but then, F# Data is an open source project and we always welcome contributions :-)). 目前,F#Data使用已擦除的类型(对C#interop不好)但我们实际上正在考虑切换到生成的类型,这将使​​提供者可以从C#(通过小型F#项目)使用 - 所以,我认为类型提供者是答案在这里,他们可能需要一些改进才能完成你的项目(但是,F#Data是一个开源项目,我们总是欢迎贡献:-))。

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

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