问题
So, I was trying to get this simple test working in an F# console app:
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
I expected MEF to get the function properly resolved, but it doesn't. Instead, I get this:
An unhandled exception of type
'System.ComponentModel.Composition.CompositionContractMismatchException'
occurred in System.ComponentModel.Composition.dllAdditional 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]'.
- What am I missing here?
- What is the difference between
FSharpFunc(System.Int32, System.String)
andFSharpFunc``2[System.Int32, System.String]
? - What is the correct way to import/export F# functions via MEF?
回答1:
The compiler turns top-level F# functions into methods, so your example will be compiled as:
[Export(FSharpFunc<int,string>)]
public string toString(int i) { return i.ToString(); }
This is probably causing the error. You can force the compiler to produce a property getter of FSharpFunc
type by calling some operation that returns a function - even a simple identity function will don:
let makeFunc f = f
[<Export(typeof<int -> string>)>]
let toString = makeFunc <| fun (i:int) ->
i.ToString()
I have not tested this, but I think it could work. That said, it is probably safer to go with a simple single-method interface in this case.
来源:https://stackoverflow.com/questions/35543585/f-and-mef-exporting-functions