如何为提供的方法

时间:2016-01-28 17:28:45

标签: f# type-providers

F#4.0引入了为提供的方法提供静态参数的能力(参见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

我希望我提供的方法的返回类型取决于用户提供的静态参数。

我需要在DefineStaticParameters回调之外定义返回类型,以便我可以将其传递给this.AddNamespace但不幸的是,这意味着多次调用AddMethod并且最终得到一堆不必要的重载。 如果我在returnType回调中移动DefineStaticParameters的创建,则无法将其传递给AddNamespace,类型提供程序不再起作用。

如何解决这个难题?

示例代码:

[<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 ()

1 个答案:

答案 0 :(得分:1)

如果确实需要在每次使用不同的静态参数时向命名空间添加新类型,那么我认为唯一的方法是将所需信息存储在缓存中并触发{{1}当您需要向命名空间添加新类型时,请事后重新填充缓存中的所有类型。