2012-04-27 9 views
4

提供された型の内部表現を構築する際に、コードを変更できる別のdllの内部表現の引用を間接的に呼び出します。現在型プロバイダがF#で別のDLLを呼び出す

、私はタイププロバイダを消費するとき、それは、このようなDLLを見つけることができない私に語った:

私が使用してVSを検査する場合

「ファイルまたはアセンブリXXXXまたはその依存関係の1をロードできませんでした」プロセスエクスプローラ、しかし、私はdll XXXがロードされたのを見ることができます... dllの外からのコードを引用符で受け入れるために何かする必要はありますか?

**更新**

私は簡単な例で試みたが、それを行うための特別な事せずに、このような外部のDLLを呼び出すことが可能であると思われます。私のケースでは、すべてのdll XXXがロードされていることに依存しています.devenv.exe自体をデバッグすると、プロセスエクスプローラとモジュールウィンドウに表示されます。

どこから見てもわかりません。内部例外があります。

**更新**

私はこのパスのいずれかでxxxはdllファイルとその依存関係をコピーする場合、コンパイラは正常に動作します。 私はまだdevenv.exeがロードされているがアクセス可能でないことを正しく表示するために何を引き起こすことができるのだろうかと思います。

=== Pre-bind state information === 
LOG: User = xxx\Administrator 
LOG: DisplayName = bloombergapi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 
(Fully-specified) 
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/ 
LOG: Initial PrivatePath = NULL 
Calling assembly : (Unknown). 
=== 
LOG: This bind starts in default load context. 
LOG: Using application configuration file: C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio\11.0\devenv.exe.config 
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. 
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/bloombergapi/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PublicAssemblies/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PublicAssemblies/bloombergapi/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/bloombergapi/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Microsoft/TemplateProviders/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Microsoft/TemplateProviders/bloombergapi/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Platform/Debugger/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/CommonExtensions/Platform/Debugger/bloombergapi/bloombergapi.DLL. 
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio 11.0/Common7/IDE/PrivateAssemblies/DataCollectors/bloombergapi.DLL. 

...

ANSWER

タイプ別のライブラリから引数として取る関数を呼び出すことが不可能です。ユニオン型は動作しますが、適切でないタイプは... これは

--Library.dll

namespace Library 

module SampleModule = 
    type LocalUnion = | LocalUnion of int 

    type Localtype() = 
     member x.value = 2 

--LibraryTP.dll

namespace LibraryTP 

module Module = 
    open System.Reflection 
    open Samples.FSharp.ProvidedTypes 
    open FSharpx.TypeProviders.DSL 
    open Microsoft.FSharp.Core.CompilerServices 

    let f a = 
    Library.SampleModule.sampleFunction a a 

    let g (a:Library.SampleModule.LocalUnion) = 
     let (Library.SampleModule.LocalUnion(v)) = a 
     v 

    let ftype (a:Library.SampleModule.Localtype) = 
     a.value 

    let createTP ns = 
     erasedType<obj> (Assembly.GetExecutingAssembly()) ns "Outside" 
     |> staticParameter "file" 
      (fun typeName (parameterValues:string) -> 
       erasedType<obj> (Assembly.GetExecutingAssembly()) ns typeName 
       |+!> ( provideProperty 
          "test"        //OK 
          typeof<float>     
          (fun args -> <@@ g (f 2) @@>)  
         |> makePropertyStatic 
        ) 
       |+!> ( provideProperty 
          "test2"        //KO 
          typeof<int>     
          (fun args -> <@@ ftype (Library.SampleModule.Localtype()) @@>) 
         |> makePropertyStatic 
        ) 
       ) 

    [<TypeProvider>] 
    type public CustomTypeProvider(cfg:TypeProviderConfig) as this = 
     inherit TypeProviderForNamespaces() 

     do this.AddNamespace("TP", [createTP "TP"]) 

    [<TypeProviderAssembly>] 
    do() 

--program下に例示されている .fs

type sampleValue = TP.Outside<""> 

    [<EntryPoint>] 
    let main(args) = 
     let t = sampleValue.Test  //OK 
     let tt = sampleValue.Test2  //KO 
+0

愚かな質問だと思いますが、dll XXXのすべての依存関係もメモリにロードされていますか? –

答えて

10

あなたのアセンブリは別のbinding context。見積もりを逆シリアル化すると、アセンブリを1つのバインディングコンテキストにロードしようとする可能性があり、アセンブリが既に別のコンテキストにロードされていてもこの試行が失敗することがあります。型プロバイダの設計時アセンブリの回避策として、ハンドラをAssemblyResolve eventに追加して、既にロードされているアセンブリのリストでターゲットアセンブリを見つけようとします。

do System.AppDomain.CurrentDomain.add_AssemblyResolve(fun _ args -> 
     let name = System.Reflection.AssemblyName(args.Name) 
     let existingAssembly = 
      System.AppDomain.CurrentDomain.GetAssemblies() 
      |> Seq.tryFind(fun a -> System.Reflection.AssemblyName.ReferenceMatchesDefinition(name, a.GetName())) 
     match existingAssembly with 
     | Some a -> a 
     | None -> null 
     ) 
+0

それはそれでした。私は非常に多くの提案をしてくれてありがとうございます。それらの新しいタイピングマシンであなたはそれほど悪くはありません。 – nicolas

+0

私はこれを試してみましたが、必要なアセンブリが(明らかに)ロードされていなかったので、ResolveEventHandlerに親ディレクトリの "packages"フォルダを探し、そこに一致するDLLを探すようにしました。 –

関連する問題