F# 和 MEF:导出函数

F# and MEF: Exporting Functions

所以,我试图让这个简单的测试在 F# 控制台应用程序中运行:

open System.Reflection
open System.ComponentModel.Composition
open System.ComponentModel.Composition.Hosting

[<Export(typeof<int -> string>)>]
let toString(i: int) = i.ToString()

[<EntryPoint>]
let main argv = 
    use catalog = new AssemblyCatalog(Assembly.GetEntryAssembly())
    use container = new CompositionContainer(catalog)

    let myFunction = container.GetExportedValue<int -> string>()
    let result = myFunction(5)
    0

我希望 MEF 能够正确解析函数,但事实并非如此。 相反,我得到这个:

An unhandled exception of type 'System.ComponentModel.Composition.CompositionContractMismatchException' occurred in System.ComponentModel.Composition.dll

Additional information:

Cannot cast the underlying exported value of type 'Program.toString (ContractName="Microsoft.FSharp.Core.FSharpFunc(System.Int32,System.String)")' to type 'Microsoft.FSharp.Core.FSharpFunc``2[System.Int32,System.String]'.

编译器将顶级 F# 函数转换为方法,因此您的示例将被编译为:

[Export(FSharpFunc<int,string>)]
public string toString(int i) { return i.ToString(); }

这可能是导致错误的原因。您可以通过调用一些 returns 函数的操作来强制编译器生成 FSharpFunc 类型的 属性 getter - 即使是简单的恒等函数也不会:

let makeFunc f = f 

[<Export(typeof<int -> string>)>]
let toString = makeFunc <| fun (i:int) -> 
  i.ToString()

我没有测试过这个,但我认为它可以工作。也就是说,在这种情况下使用简单的单一方法接口可能更安全。