2012-04-17 8 views
6

Ho difficoltà a decifrare la sezione "Fornire tipi generati" di Type Provider Tutorial. Il tutorial fornisce le seguenti specifiche.Quando è necessario chiamare il membro "ConvertToGenerated" per generare tipi utilizzando un provider di tipi

"È inoltre necessario chiamare ConvertToGenerated su un tipo fornito di radice i cui tipi nidificati formano un insieme chiuso di tipi generati.Questa chiamata emette la definizione di tipo fornita fornita e le sue definizioni di tipo annidato in un assembly e regola la proprietà Assembly di tutte le fornite digita le definizioni per restituire quell'assembly.L'assembly viene emesso solo quando la proprietà Assembly sul tipo di root viene acceduta per la prima volta.Il compilatore F # host accede a questa proprietà quando elabora una dichiarazione di tipo generativo per il tipo. "

Non so dove posizionare la chiamata ConvertToGenerated e non sono sicuro sui requisiti del parametro del nome del file di assembly. Qualcuno può fornire un esempio? Grazie.

+1

È necessario pubblicare l'aggiornamento come risposta. Sarà utile per i futuri visitatori. – pad

risposta

4

Dopo l'aiuto del team F # ho risolto il mio problema. Questo è quello che ho fatto.

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() 

Il framework TypeProvider.Emit elimina automaticamente l'assembly generato. Commenta la seguente affermazione se vuoi che resti fedele.

File.Delete assemblyFileName 

Un altro Gotcha ho trovato è che mentre ero in grado di fornire i tipi che derivano dai tipi di valore (come decimale) quando IsErased = true, non ero in grado di fornire questi tipi derivati ​​quando IsErased = false. Questo perché i tipi di valore sono sigillati, quindi non è possibile generare un tipo "reale" che deriva da un tipo di valore.

Problemi correlati