2012-04-17 3 views
6

Trudno jest odszyfrować sekcję "Providing Generated Types" pod numerem Type Provider Tutorial. Samouczek zawiera poniższą specyfikację.Kiedy należy wywołać element "ConvertToGenerated", aby wygenerować typy przy użyciu dostawcy typu

"Należy również wywołać metodę ConvertToGenerated na podanym typie katalogu głównego, którego typy zagnieżdżone tworzą zamknięty zestaw generowanych typów. Wywołanie emituje podaną definicję typu i zagnieżdżone definicje typów do zespołu i dostosowuje właściwość Assembly wszystkich dostarczonych typów. Definicje typów zwracają ten zestaw Zespół jest emitowany tylko wtedy, gdy dostęp do właściwości Assembly na typie root jest uzyskiwany po raz pierwszy .. Kompilator F # hosta uzyskuje dostęp do tej właściwości, gdy przetwarza deklarację typu generatywnego dla typu. "

Nie wiem, gdzie umieścić wywołanie ConvertToGenerated i nie jestem pewien co do wymagań parametru nazwy pliku zespołu. Czy ktoś może podać przykład? Dzięki.

+1

Należy opublikować aktualizację jako odpowiedź. Będzie to pomocne dla przyszłych odwiedzających. – pad

Odpowiedz

4

Po pomocy zespołu F # rozwiązałem mój problem. Oto co zrobiłem.

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

Struktura TypeProvider.Emit automatycznie czyści wygenerowany zespół. Skomentuj następujące stwierdzenie, jeśli chcesz, aby się trzymał.

File.Delete assemblyFileName 

Innym haczyka znalazłem jest to, że gdy byłem w stanie dostarczyć rodzaje, które wynikają z typów wartości (jak po przecinku), gdy IsErased = true, nie był w stanie dostarczyć te typy pochodzące gdy IsErased = false. Wynika to z faktu, że typy wartości są zapieczętowane, więc nie można wygenerować typu "rzeczywistego", który pochodzi od typu wartości.

Powiązane problemy