如何创建可以从c#中使用的f#类型提供程序?

时间:2022-02-08 12:56:29

If I use the F# Type Providers from the assembly FSharp.Data.TypeProviders 4.3.0.0, I am able to create types in a very simple F# library. I am then able to use those types without any dependency on the assembly FSharp.Data.TypeProviders. That is pretty sweet! Here is an example:

如果我使用来自汇编FSharp.Data的f#类型提供程序。类型提供程序4.3.0.0,我可以在一个非常简单的f#库中创建类型。然后,我就可以使用这些类型,而不需要依赖于assembly fsharp.data . typeprovider。很甜!这是一个例子:

I created an F# library project called TryTypeProviders. I put this in the .fs:

我创建了一个名为trytypeprovider的f#库项目。我把这个写在。fs:

module TryTypeProviders
type Northwind = Microsoft.FSharp.Data.TypeProviders.ODataService

I then am able to use the F# library from a C# project:

然后我就可以从c#项目中使用f#库:

public static void Main()
{
    var c = new TryTypeProviders.Northwind();
    foreach (var cust in c.Customers)
        Console.WriteLine("Customer is: " + cust.ContactName);
    Console.ReadKey(true);
}

I haven't been able to find any working examples of how to create a type provider like this. The type providers in FSharpx.TypeProviders are not accessible from C#. My guess is that they are erased types and not generated types. I'm still a little fuzzy on which is which, but it is defined here as:

我还没有找到如何创建这样的类型提供程序的任何工作示例。FSharpx中的类型提供程序。从c#无法访问类型提供程序。我的猜测是它们是擦除的类型,而不是生成的类型。我还是有点搞不清哪个是哪个,但是这里的定义是:

  1. Generated types are real .NET types that get embedded into the assembly that uses the type provider (this is what the type providers that wrap code generation tools like sqlmetal use)
  2. 生成的类型是真正的。net类型,它们被嵌入到使用类型提供程序的程序集中(这是类型提供者,它封装了代码生成工具,如sqlmetal使用)
  3. Erased types are simulated types which are represented by some other type when the code is compiled.
  4. 擦除类型是在编译代码时由其他类型表示的模拟类型。

The samples from the F# 3.0 Sample Pack mentioned in the MSDN tutorial are not working for me. They build, but when I try to use them I get errors.

MSDN教程中提到的f# 3.0示例包中的示例对我不起作用。它们会构建,但当我尝试使用它们时,会出现错误。

open Samples.FSharp.RegexTypeProvider
type PhoneNumberRegEx = CheckedRegexProvider< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">
open Samples.FSharp.MiniCsvProvider
type csv = MiniCsvProvider<"a.csv">

It was last released in March of 2011 and my guess is that they don't yet reflect the final version of type providers that shipped with Visual Studio 2012.

它是在2011年3月发布的,我的猜测是它们还没有反映出与Visual Studio 2012一起发布的类型提供商的最终版本。

F# Type Providers look like a great technology, but we need help building them. Any help is appreciated.

f#类型的提供者看起来是一个伟大的技术,但是我们需要帮助来构建它们。任何帮助都是感激。

1 个解决方案

#1


36  

The reason why standard type providers (for OData, LINQ to SQL and WSDL) work with C# is that they generate real .NET types behind the cover. This is called generative type provider. In fact, they simply call the code generation tool that would be called if you were using these technologies from C# in a standard way. So, these type providers are just wrappers over some standard .NET tools.

标准类型的提供者(对于OData、LINQ to SQL和WSDL)使用c#的原因是它们在幕后生成了真正的。net类型。这被称为生成类型提供程序。事实上,它们只是调用代码生成工具,如果您以标准的方式使用c#中的这些技术,就会调用该工具。因此,这些类型提供程序只是一些标准的。net工具的包装。

Most of the providers that are newly written are written as erasing type providers. This means that they only generate "fake" types that tell the F# compiler what members can be called (etc.) but when the compiler compiles them, the "fake" types are replaced with some other code. This is the reason why you cannot see any types when you're using the library from C# - none of the types actually exist in the compiled code.

大多数新编写的提供程序都被编写为删除类型提供程序。这意味着它们只生成“假”类型,这些类型告诉f#编译器可以调用什么成员(等等),但是当编译器编译它们时,“假”类型就会被其他代码所取代。这就是为什么在使用c#的库时看不到任何类型的原因—在编译的代码中实际上没有类型。

Unless you're wrapping existing code-generator, it is easier to write erased type provider and so most of the examples are written in this way. Erasing type providers have other beneftis - i.e. they can generate huge number of "fake" types without generating excessively big assemblies.

除非您正在包装现有的代码生成器,否则更容易编写擦除类型提供程序,因此大多数示例都是这样编写的。擦除类型的提供者还有其他的好处,即它们可以生成大量的“假”类型,而不会生成过多的大型程序集。

Anyway, there is a brief note "Providing Generated Types" in the MSDN tutorial, which has some hints on writing generative providers. However, I'd expect most of the new F# type providers to be written as erasing. It notes that you must have a real .NET assembly (with the generated types) and getting that is not simplified by the F# helpers for building type providers - so you'll need to emit the IL for the assembly or generate C#/F# code and compile that (i.e. using CodeDOM or Roslyn).

无论如何,MSDN教程中有一个简短的说明“提供生成类型”,其中有一些关于编写生成提供程序的提示。但是,我希望大多数新的f#类型的提供者都被写为擦除。它指出,你必须有一个真正的net程序集(使用生成的类型),这不是f#助手简化的建筑类型供应商——所以你需要排放的IL组装或生成c# / f#代码和编译(即使用CodeDOM或Roslyn)。

#1


36  

The reason why standard type providers (for OData, LINQ to SQL and WSDL) work with C# is that they generate real .NET types behind the cover. This is called generative type provider. In fact, they simply call the code generation tool that would be called if you were using these technologies from C# in a standard way. So, these type providers are just wrappers over some standard .NET tools.

标准类型的提供者(对于OData、LINQ to SQL和WSDL)使用c#的原因是它们在幕后生成了真正的。net类型。这被称为生成类型提供程序。事实上,它们只是调用代码生成工具,如果您以标准的方式使用c#中的这些技术,就会调用该工具。因此,这些类型提供程序只是一些标准的。net工具的包装。

Most of the providers that are newly written are written as erasing type providers. This means that they only generate "fake" types that tell the F# compiler what members can be called (etc.) but when the compiler compiles them, the "fake" types are replaced with some other code. This is the reason why you cannot see any types when you're using the library from C# - none of the types actually exist in the compiled code.

大多数新编写的提供程序都被编写为删除类型提供程序。这意味着它们只生成“假”类型,这些类型告诉f#编译器可以调用什么成员(等等),但是当编译器编译它们时,“假”类型就会被其他代码所取代。这就是为什么在使用c#的库时看不到任何类型的原因—在编译的代码中实际上没有类型。

Unless you're wrapping existing code-generator, it is easier to write erased type provider and so most of the examples are written in this way. Erasing type providers have other beneftis - i.e. they can generate huge number of "fake" types without generating excessively big assemblies.

除非您正在包装现有的代码生成器,否则更容易编写擦除类型提供程序,因此大多数示例都是这样编写的。擦除类型的提供者还有其他的好处,即它们可以生成大量的“假”类型,而不会生成过多的大型程序集。

Anyway, there is a brief note "Providing Generated Types" in the MSDN tutorial, which has some hints on writing generative providers. However, I'd expect most of the new F# type providers to be written as erasing. It notes that you must have a real .NET assembly (with the generated types) and getting that is not simplified by the F# helpers for building type providers - so you'll need to emit the IL for the assembly or generate C#/F# code and compile that (i.e. using CodeDOM or Roslyn).

无论如何,MSDN教程中有一个简短的说明“提供生成类型”,其中有一些关于编写生成提供程序的提示。但是,我希望大多数新的f#类型的提供者都被写为擦除。它指出,你必须有一个真正的net程序集(使用生成的类型),这不是f#助手简化的建筑类型供应商——所以你需要排放的IL组装或生成c# / f#代码和编译(即使用CodeDOM或Roslyn)。