类提供商调用F#另一个DLL(Type provider calling another dll i

2019-06-24 00:39发布

在为提供的类型的内部表示的建设,我的报价呼吁间接为我喜欢的类型,另一个DLL,它的代码,我可以修改的内部表示。

目前,当我消费型供应商,告诉我它无法找到这样的dll:

“无法加载文件或程序XXXX或其依赖的一个”

当我检查VS使用Process Explorer的,不过,我可以看到该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.

...

回答

这似乎是不可能来调用一个函数,它作为一个参数从另一个库类型。 一名工会类型的作品,但不是一个类型正确的...这是如下图所示

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

Answer 1:

您的组件可以被加载到不同的绑定上下文 。 当报价进行反序列化可以尝试到组件加载到一个绑定上下文即使组件已经加载到另一个背景下,这个尝试可能会失败。 作为您的类型提供设计时的解决方法组装您可以添加处理程序的AssemblyResolve事件 ,并试图找到在已加载的程序集列表中靶组件。

    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
        )


文章来源: Type provider calling another dll in F#