Question

How do I access the (runtime) instance from the implementation of the a ProvidedMethod

that is if foo is of a provided type and the erased type is Bar with a method named Execute Then given this code

foo.Execute() 

I wish the ProvidedMethod to equal this

bar.Execute() //where bar is an object of type Bar

What I have is this

//p is a MethodInfo that represents Bar.Execute and m is the ProvidedMethod 
objm.InvokeCode <- fun args -> <@@ p.Invoke(--what goes here--,null) @@>
Was it helpful?

Solution

The instance is passed as the first expression in the args array, so you can access it from there.

Also, the InvokeCode that you need to build should not capture the method info p and call Invoke on it using reflection. Instead, you need to build an F# quotation (akin to expression tree) that represents the invocation.

So, you need to write something like this:

objm.InvokeCode <- (fun args -> 
  // The 'args' parameter represents expressions that give us access to the 
  // instance on which the method is invoked and other parameters (if there are more)
  let instance = args.[0]
  // Now we can return quotation representing a call to MethodInfo 'p' with 'instance'
  Expr.Call(instance, p) )

Note that I did not use <@@ .. @@> here because you already have MethodInfo for the method that you want to call. If you instead wanted to call a method ProviderRuntime.DoStuff(instance) then you could use quotation literals:

objm.InvokeCode <- (fun args -> 
  let instance = args.[0]
  <@@ ProviderRuntime.DoStuff(%%instance) @@> )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top