2012-04-17 35 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 =假。这是因为值类型是密封的,所以不可能生成从值类型派生的“真实”类型。