2012-04-17 36 views
6

我很難破譯Type Provider Tutorial的「提供生成類型」部分。本教程提供了以下規格。 「什麼時候需要調用「ConvertToGenerated」成員來使用類型提供程序生成類型

」您還必須調用ConvertToGenerated提供的根類型,其嵌套類型形成一組封閉的生成類型。該調用將給定的提供的類型定義及其嵌套類型定義發佈到程序集中,並調整所有提供的Assembly屬性類型定義來返回該程序集,只有在首次訪問根類型的程序集屬性時,程序集纔會被髮出,主機F#編譯器在處理該類型的生成類型聲明時會訪問該屬性。

我不知道在哪裏放置ConvertToGenerated調用,我不確定程序集文件名參數的要求。有人可以提供一個例子嗎?謝謝。

+1

您應該將更新發布爲答案。這將有助於未來的遊客。 – pad 2012-04-20 17:37:55

回答

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 

有一個問題是,我發現我的同時能夠提供從值類型派生類型(如十進制)時IsErased =真,我無法提供這些派生類型時IsErased =假。這是因爲值類型是密封的,所以不可能生成從值類型派生的「真實」類型。