在F#类型提供程序中发出生成的类型 [英] Emitting Generated Types in F# type providers
问题描述
我创建了一个简单的生成类型提供程序,该程序在重新组合类型时采用程序集的路径,以将它们置于类型提供程序命名空间下(如果需要,可以进行内部化处理).
有关代码的链接在这里 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'时出现问题:类型3的程序类型错误,错误:mref =".ctor"的GetMethodRefAsMethodDefIdx错误,错误:类型'异常抛出Microsoft.FSharp.Compiler.AbstractIL.ILBinaryWriter + MethodDefNotFound. FSC 1 1 TypeProviders.Tests
示例包中给出的生成类型的示例似乎定义了任何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
预先感谢
免责声明:浏览器编译的解决方案
我相信在这里您不需要创建生成的类型来包装现有的类型=>这样就可以了
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
I have created a simple generating type provider that takes the path to an assembly at reorganizes the types, to bring them under the type providers namespace, (sort of Internalising if you like).
The link to the code concerned is here https://github.com/colinbull/Playground
Now the types seem to be provided correctly,
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
since the displays in VS without any reported errors. However when I compile this assembly the IL seems to get emitted incorrectly with the following error.
Error 1: A problem occurred writing the binary 'obj\Debug\TypeProviders.Tests.exe': Error in pass3 for type Program, error: Error in GetMethodRefAsMethodDefIdx for mref = ".ctor", error: Exception of type 'Microsoft.FSharp.Compiler.AbstractIL.ILBinaryWriter+MethodDefNotFound' was thrown. FSC 1 1 TypeProviders.Tests
Examples given for generated types given in samples pack doesn't seem to have any StaticParameters
defined which requires a type with the provided type name to be returned. In this case how do I emit the types in the provided assembly? Currently I am doing the following
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
Thanks in advance
Disclaimer: browser compiled solutions
I believe here you don't need to create generated types that will wrap exiting types => this should work
let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
let existingAssembly = Assembly.LoadFrom(assemblyPath)
for ty in providedAssembly.GetExportedTypes() do
reqType.AddMember(ty)
reqType
You can also try this one:
let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
reqType.AddAssemblyTypesAsNestedTypesDelayed(fun() -> Assembly.LoadFrom assemblyPath)
reqType
this one will preserve namespace so declaration of type C will look like
type C = T.SimpleLib.Class1
这篇关于在F#类型提供程序中发出生成的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!