2013-03-23 54 views
1

我想寫我的第一個類型的提供者,想知道是否有人可以指出我要去哪裏錯了。類型提供程序沒有被反射看到

我已經使用了freebase示例來工作。我試圖通過基本的位來篩選一些非常基本的實例化的東西,但顯然錯過了某些東西或者沒有把它完全正確(可能與名稱空間有關)。我只是試圖讓這條線的工作

type tp = MyFirstTypeProvider.DataProvider<username="username",password="password",product=prodId> 

智能感知是看到了DataProvider,但我發現了波浪說,該類型的引用可以找到的類型不能在大會上找到。

namespace MyFirstProvider 

type internal MyFirstRuntimeInfo(config: TypeProviderConfig) = 
    let runtimeAssembly = Assembly.LoadFrom(config.RuntimeAssembly) 

    member val DataContextType = runtimeAssembly.GetType("MyFirstProvider.Runtime.DataContext") 
    member this.RuntimeAssembly = runtimeAssembly 

// This type defines the type provider. When compiled to a DLL, it can be added 
// as a reference to an F# command-line compilation, script, or project. 
[<TypeProvider>] 
type public Types(config: TypeProviderConfig) as this = 
    inherit TypeProviderForNamespaces() 

    let bfRuntimeInfo = MyFirstRuntimeInfo(config) 

    let rootNamespace = "MyFirstProvider" 

    let defaultUsername = "xxxxxxxxxxx" 
    let defaultPassword = "yyyyyyyyyy" 
    let defaultProductId = -1  
    let defaultToken = "none" 

    let createDataContext = bfRuntimeInfo.DataContextType.GetMethod("_Create") 

    let createTypes(username, password, productId, rootTypeName) =      let bf = new MyFirstProvider.Requests.Queries(defaultToken) 
    let schema = new MyFirstProvider.Schema.SchemaConnection(bf) 
    let rootType = ProvidedTypeDefinition(bfRuntimeInfo.RuntimeAssembly,rootNamespace,rootTypeName,baseType=Some typeof<obj>, HideObjectMethods=true) 
    let theServiceType = ProvidedTypeDefinition("Service",baseType=Some bfRuntimeInfo.DataContextType, HideObjectMethods=true) 
    let theServiceTypesClass = ProvidedTypeDefinition("ServiceTypes",baseType=Some typeof<obj>,HideObjectMethods=true) 
    theServiceTypesClass.AddMembers [ theServiceType ]  
    rootType.AddMembers [ theServiceTypesClass ] 
    rootType.AddMembersDelayed (fun() -> 
     [ yield ProvidedMethod ("GetDataContext", [], theServiceType, IsStaticMethod=true, 
           InvokeCode = (fun _args -> Expr.Call(createDataContext, [ Expr.Value defaultUsername; Expr.Value defaultPassword; Expr.Value defaultProductId ]))) 
     ])   
    rootType 

    let MyFirstType = createTypes(defaultUsername, defaultPassword, defaultProductId, "Data") 
    let paramMyFirstType = ProvidedTypeDefinition(bfRuntimeInfo.RuntimeAssembly, rootNamespace, "DataProvider", Some(typeof<obj>), HideObjectMethods = true) 
    let usernameParam = ProvidedStaticParameter("username", typeof<string>, defaultUsername) 
    let passwordParam = ProvidedStaticParameter("password", typeof<string>, defaultPassword) 
    let productIdParam = ProvidedStaticParameter("productId", typeof<int>, defaultProductId) 

    do paramMyFirstType.DefineStaticParameters([usernameParam;passwordParam;productIdParam], fun typeName providerArgs -> 
     let username = (providerArgs.[0] :?> string) 
     let password = (providerArgs.[1] :?> string) 
     let productId = (providerArgs.[2] :?> int) 
     createTypes(username, password, productId, typeName)) 

    do 
     this.AddNamespace(rootNamespace, [MyFirstType ]) 
     this.AddNamespace(rootNamespace, [paramMyFirstType ]) 

[<assembly:TypeProviderAssembly>] 
do() 

很多thx提前。

回答

3

當我嘗試編譯你的類型提供商,在腳本文件中引用它,參考#r "provider.dll"是強調有一個紅色的波浪,上面寫着:

The type provider 'MyFirstProvider.Types' reproted an error: The type provider constructor has thrown an exception: Object reference not set to an instance of an object.

您可以通過啓動Visual Studio的第二個實例並將調試器附加到另一個實例(Debug - > Attach to Process)並打開正在調試的實例中的腳本文件來調試此類錯誤。

在你這裏張貼的樣品,在這條線出現空引用異常:

let createDataContext = bfRuntimeInfo.DataContextType.GetMethod("_Create") 

這是試圖訪問一個不存在的方法。我認爲Freebase示例是一個相對複雜的起點(在這裏,它使用一個對象來表示「數據上下文」) - 您可能想要遵循該模式,但我認爲從頭開始構建它比更容易碼)。我認爲一個很好的起點可能是Hello World type provider這很簡單,只是展示瞭如何生成新的類型,屬性和方法。

+0

thx非常。我還沒有完全熟悉「實例化」freebase類型提供者的兩種方式 - 帶和不帶api鍵 - MyProvider.Data和MyProvider.DataProvider <[params>。我想我有點期待重載類型的行爲。一旦這一分錢下降,我可以得到的東西工作! Thx再次 – 2013-03-24 10:04:18

2

我會建議,如果你正在尋找一個類型提供者的簡單例子,看看File System type provider這是一個很好的開始,因爲它沒有狀態,也沒有依賴管理來照顧。

至於爲什麼這個人有一個DLL無法找到,我認爲這是因爲這個DLL必須從您的類型提供者的DLL的位置看到。例如,在同一個目錄中。 (?你可以嘗試設置「複製本地」在構建過程中)

+0

thx非常 - 看到我的評論Tomas – 2013-03-24 09:59:27

相關問題