6

Type Provider Tutorialの「Providing Generated Types」セクションを解読するのに苦労しています。チュートリアルでは、次の仕様が提供されます。

「また、ネストされた型が生成された型の閉じたセットを形成するルート提供型で ConvertToGenerated を呼び出す必要があります。この呼び出しは、指定された提供された型定義とその入れ子にされた型定義をアセンブリに出力し、提供されたすべての型定義の Assembly プロパティを調整して返すようにします。そのアセンブリ。アセンブリは、ルート型の Assembly プロパティが初めてアクセスされたときにのみ発行されます。ホスト F# コンパイラは、型の生成型宣言を処理するときに、このプロパティにアクセスします。"

ConvertToGenerated 呼び出しを配置する場所がわかりません。また、アセンブリ ファイル名パラメーターの要件もわかりません。誰かが例を提供できますか?ありがとう。

4

1 に答える 1

4

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

私が見つけたもう 1 つの落とし穴は、IsErased=true の場合は値型 (10 進数など) から派生した型を提供できましたが、IsErased=false の場合はこれらの派生型を提供できなかったことです。これは、値型が封印されているため、値型から派生した「実際の」型を生成できないためです。

于 2012-04-21T01:15:08.687 に答える