在F#类型提供程序中发出生成的类型

时间:2013-02-25 23:19:13

标签: f# type-providers f#-3.0

我创建了一个简单的生成类型提供程序,它在重新组织类型时获取程序集的路径,将它们放在类型提供程序命名空间下(如果您愿意,可以使用内部化)。

有关代码的链接在这里 https://github.com/colinbull/Playground

现在似乎正确提供了类型,

let[<Literal>]assemblyPath = @"D:\Appdev\Playground\SimpleLib\bin\Debug\SimpleLib.dll"
type T = Inno.InternalisingProvider<assemblyPath>
type C = T.Class1

[<EntryPoint>]
let main argv = 
    let c = new C()
    printfn "Result: %A" c.X
    System.Console.ReadLine() |> ignore
    0

因为VS中的显示没有任何报告错误。但是,当我编译此程序集时,IL似乎被错误地发出以下错误。

  

错误1:编写二进制文件'obj \ Debug \ TypeProviders.Tests.exe'时出现问题:类型为Program的pass3错误,错误:GetMethodRefAsMethodDefIdx错误,mref =“。。”错误:类型异常'抛出了Microsoft.FSharp.Compiler.AbstractIL.ILBinaryWriter + MethodDefNotFound'。 FSC 1 1 TypeProviders.Tests

samples pack中给出的生成类型的示例似乎没有定义任何StaticParameters,这需要返回提供类型名称的类型。在这种情况下,如何在提供的程序集中发出类型?目前我正在做以下

  let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
      let name = Path.GetFileName(assemblyPath)
      let providedAssembly = ProvidedAssembly.RegisterGenerated(assemblyPath)

      for t in providedAssembly.GetExportedTypes() do
          let ty = createGeneratedType t
          ty.SetAssembly(providedAssembly)
          reqType.AddMember(ty)

      reqType

提前致谢

1 个答案:

答案 0 :(得分:4)

免责声明:浏览器编译解决方案

我相信你不需要创建包含exiting types =&gt;的生成类型。这应该工作

let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
    let existingAssembly = Assembly.LoadFrom(assemblyPath)

    for ty in providedAssembly.GetExportedTypes() do
        reqType.AddMember(ty)

    reqType

你也可以尝试这个:

let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
    reqType.AddAssemblyTypesAsNestedTypesDelayed(fun() -> Assembly.LoadFrom assemblyPath)
    reqType

这个将保留名称空间,因此类型C的声明将类似于

type C = T.SimpleLib.Class1