2012-04-17 2 views
6

Type Provider Tutorialの "生成された型の提供"セクションを解読するのに苦労しています。このチュートリアルでは、次の仕様を提供します。タイププロバイダを使用して型を生成するために "ConvertToGenerated"メンバを呼び出す必要がある場合

"ネストされた型が閉じられた生成型の集合を形成するルート提供型でConvertToGeneratedを呼び出す必要もあります。この呼び出しは、指定された型定義とそのネストされた型定義をアセンブリに出力し、このアセンブリは、ルート型のアセンブリプロパティが最初にアクセスされたときにのみ生成されます。ホストF#コンパイラは、その型の生成型宣言を処理するときにこのプロパティにアクセスします。

ConvertToGenerated呼び出しをどこに配置するのかわかりませんが、アセンブリファイル名パラメータの要件が不明です。誰かが例を挙げることはできますか?ありがとう。

+1

更新を回答として投稿する必要があります。将来の訪問者に役立つでしょう。 – pad

答えて

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フレームワークは、生成されたアセンブリを自動的にクリーンアップします。あなたがそれを固執したい場合は、次の文をコメントアウトしてください。ときIsErased =真の私が見つけた

File.Delete assemblyFileName 

もう一つの落とし穴は、私が(小数点以下のような)値の型から派生型を提供することができた一方でということですが、私はときIsErased = falseのこれらの派生型を提供することができませんでした。これは、値型が密封されているため、値型から派生した「実」型を生成することができないためです。

関連する問題