gpt4 book ai didi

f# - 我什么时候需要调用 "ConvertToGenerated"成员来使用类型提供程序生成类型

转载 作者:行者123 更新时间:2023-12-04 15:25:38 25 4
gpt4 key购买 nike

我很难破译 Type Provider Tutorial 的“提供生成的类型”部分.本教程提供了以下规范。

“您还必须在根提供的类型上调用 ConvertToGenerated ,该类型的嵌套类型形成一组封闭的生成类型。此调用将给定的提供类型定义及其嵌套类型定义发出到程序集中,并调整所有提供的类型定义的 Assembly 属性以返回那个程序集。只有在第一次访问根类型上的程序集属性时才会发出程序集。主机 F# 编译器在处理该类型的生成类型声明时确实访问了这个属性。”

我不知道将 ConvertToGenerated 调用放在哪里,也不确定程序集文件名参数的要求。有人可以提供一个例子吗?谢谢。

最佳答案

在 F# 团队的帮助下,我解决了我的问题。这就是我所做的。

namespace Types

open System
open System.Data
open System.IO
open System.Linq
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
open Microsoft.FSharp.TypeProvider.Emit
open Microsoft.FSharp.Core.CompilerServices

type DatabaseSchema =
SqlDataConnection<"Data Source=(local);Initial Catalog=Test;Integrated Security=SSPI;">

[<TypeProvider>]
type public MeasureTypeProvider(cfg:TypeProviderConfig) as this =
inherit TypeProviderForNamespaces()

let assembly = System.Reflection.Assembly.GetExecutingAssembly()
let typesNamespace = "Types.Domain"
let providedTypeBuilder = ProvidedTypeBuilder.Default
let db = DatabaseSchema.GetDataContext()

let types =
query { for m in db.Table do select m }
|> Seq.map(fun dataEntity ->
let className:string = dataEntity.Identifier
let providedTypeDefinition =
ProvidedTypeDefinition(className = className,
baseType = Some typeof<obj>,
IsErased=false)
providedTypeDefinition.AddMember(
ProvidedConstructor([], InvokeCode = fun [] -> <@@ obj() @@>))
providedTypeDefinition
) |> Seq.toList

let rootType =
let providedTypeDefinition =
ProvidedTypeDefinition(assembly,
typeNamespace,
"DomainTypes",
Some typeof<obj>,
IsErased=false)
providedTypeDefinition.AddMembersDelayed(fun () -> types)
this.AddNamespace(typesNamespace, [providedTypeDefinition])
providedTypeDefinition

let path = Path.GetDirectoryName(assembly.Location) + @"\GeneratedTypes.dll"
do rootMeasureType.ConvertToGenerated(path)

[<assembly:TypeProviderAssembly>]
do()

TypeProvider.Emit 框架会自动清理生成的程序集。如果您希望它继续存在,请注释掉以下语句。
File.Delete assemblyFileName

我发现的另一个问题是,虽然当 IsErased=true 时我能够提供从值类型(如十进制)派生的类型,但当 IsErased=false 时我无法提供这些派生类型。这是因为值类型是密封的,因此不可能生成从值类型派生的“真实”类型。

关于f# - 我什么时候需要调用 "ConvertToGenerated"成员来使用类型提供程序生成类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10198132/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com