F# 4.0 introduced the ability to provide static parameters to provided methods (see http://blogs.msdn.com/b/fsharpteam/archive/2014/11/12/announcing-a-preview-of-f-4-0-and-the-visual-f-tools-in-vs-2015.aspx)
I want the return type of my provided method to depend upon the static parameters the user supplies.
I need to define the return type outside of the DefineStaticParameters callback in order that I can pass it to this.AddNamespace but unfortunately this means that AddMethod gets called multiple times and I end up with a bunch of unwanted overloads.
If I move the creation of returnType inside the DefineStaticParameters callback then I cannot pass it to AddNamespace and the type provider no longer functions.
How do I resolve this conundrum?
Example code:
[<TypeProvider>]
type MyTypeProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces ()
let ns = "Acme"
let asm = Assembly.GetExecutingAssembly()
let t = ProvidedTypeDefinition(asm, ns, "MyStaticClass", Some typeof<obj>, IsErased = true)
let returnType = ProviderImplementation.ProvidedTypes.ProvidedTypeDefinition(asm, ns, "MyReturnType", Some typeof<obj>, IsErased = true, HideObjectMethods = true)
let myStaticMethod =
let m = ProvidedMethod("SomeStaticMethod", [], typeof<obj>, IsStaticMethod = true)
m.DefineStaticParameters(staticParams, fun nm args ->
let providedMethod = ... // Generate a method for the return type depending on the args
returnType.AddMember(providedMethod) // PROBLEM: This gets called multiple times and adds unwanted overloads to my returnType
let m2 =
let myParam = ProvidedParameter("foo", typeof<int>)
ProvidedMethod(nm, [myParam], returnType, IsStaticMethod = true)
m2.InvokeCode <- fun args3 ->
<@@
// invoke code goes here
@@>
t.AddMember(m2)
m2
)
m
do
t.AddMember(myStaticMethod)
this.AddNamespace(ns, [t;returnType])
[<assembly:TypeProviderAssembly>]
do ()