I am playing with type providers and I am trying to compile a quotation into a public static method of a new generated type. Here is what I have:
let CreateType<'i> name methodName quotation =
let assemblyName = new AssemblyName(Name = "tmpAssembly")
let assemblyBuilder =
System.AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave)
let filename = "tmpAssembly.dll"
let tmpModule = assemblyBuilder.DefineDynamicModule(filename,filename)
// create a new type builder
let typeBuilder =
tmpModule.DefineType(
name,
TypeAttributes.Public ||| TypeAttributes.Class,
null, // parentType
[|typeof<'i>|])
let attr = MethodAttributes.Public ||| MethodAttributes.HideBySig ||| MethodAttributes.Static
let methodImpl =
typeBuilder.DefineMethod(
methodName,
attr,
typeof<unit>, // todo
[||]) // todo
let il = methodImpl.GetILGenerator()
// compile quotation to method
typeBuilder.CreateType()
I know there is a .Compile() method but I think that’s not what I need. Any ideas?
I haven’t really played with the F# 3.0 release yet, but I think that you don’t need to generate IL code yourself. The post by Keith explains that there are two types of type providers – generated that create a real .NET type (that exists in some library) and erased that create a fake type and then give the compiler an expression tree to be used in place of the calls to the fake type.
It seems to me that you’re trying to implement generated type provider in a situation where erased type would be more appropriate. In the erased case, you should be just able to return the .NET
Expression<..>type (not the F# quotation though, but you can useToLinqExpressionfrom PowerPack) and the F# compiler will compile that for you.However, I haven’t played with it yet, so I don’t know what’s the exact mechanism.