F # and MEF: Export Functions

So, I tried to get this simple test working in a F # console application:

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 return the function correctly, but that is not the case. Instead, I get the following:

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]'.

  • What am I missing here?
  • What is the difference between FSharpFunc(System.Int32, System.String) and FSharpFunc``2[System.Int32, System.String] ?
  • What is the correct way to import / export F # functions through MEF?
+2
source share
1 answer

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 create a getter property of type FSharpFunc by calling some operation that returns a function - even a simple identification function will not:

 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 might work. However, in this case, it is probably safer to use a simple interface with one method.

+3
source

Source: https://habr.com/ru/post/1246719/


All Articles