1

私は最初のタイプのプロバイダーを作成しようとしていますが、誰かが私が間違っているところを指摘できるかどうか疑問に思っています。

私はfreebaseサンプルを使用して作業しました。私は、非常に基本的なインスタンス化を取得するために重要な部分をふるいにかけようとしましたが、明らかに何かを見逃したか、完全に正しく取得できませんでした(おそらく名前空間に関連して)。私は単にこの行を機能させようとしています

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

Intellisenseは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。

4

2 に答える 2

3

タイププロバイダーをコンパイルしてスクリプトファイルで参照しようとすると、参照に#r "provider.dll"は次のような赤い波線で下線が引かれます。

タイププロバイダー'MyFirstProvider.Types'はエラーを再現しました:タイププロバイダーコンストラクターが例外をスローしました:オブジェクト参照がオブジェクトのインスタンスに設定されていません。

このようなエラーをデバッグするには、Visual Studioの2番目のインスタンスを起動し、デバッガーを別のインスタンスにアタッチして([デバッグ]-> [プロセスにアタッチ])、デバッグ中のインスタンスでスクリプトファイルを開きます。

ここに投稿したサンプルでは、​​null参照例外が次の行で発生します。

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

これは、存在しないメソッドにアクセスしようとしています。Freebaseサンプルは比較的複雑な出発点だと思います(ここでは、「データコンテキスト」を表すためにオブジェクトを使用しています。そのパターンに従うことをお勧めしますが、既存のサンプルを適応させるよりも、最初から作成する方が簡単だと思います。コード)。良い出発点は、 Hello Worldタイププロバイダーであると思います。これは、はるかに単純で、新しいタイプ、プロパティ、およびメソッドを生成する方法を示しているだけです。

于 2013-03-23T18:46:00.110 に答える
2

タイププロバイダーの簡単な例を探している場合は、ファイルシステムタイププロバイダーを確認することをお勧めします。これは、状態や依存関係の管理がないため、開始するのに適した場所です。

これが見つからないdllを持っている理由については、タイププロバイダーのdllがある場所からこのdllを確認する必要があるためだと思います。つまり、たとえば、同じディレクトリにあります。(ビルドプロセスで「ローカルコピー」を設定してみることができますか?)

于 2013-03-23T16:49:09.630 に答える