I'm trying to create a type provider that inherits from this type:
type BaseType() =
member val Member : string = "" with get, set
But I don't know how to reference Member using "this" or "base", say, in the constructor. Here's an example of what I'm trying to do:
[<TypeProvider>]
type BasicProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces ()
let asm, ns = Assembly.GetExecutingAssembly(), "Namespace"
let createTypes () =
let myType = ProvidedTypeDefinition (asm, ns, "ProvidedType", Some typeof<BaseType>)
let ctor =
ProvidedConstructor [
ProvidedParameter("inputString", typeof<string>) ]
do ctor.InvokeCode <-
fun parameters ->
// base.Member doesn't actually work - how can one do this?
<@@ do (base: BaseType).Member <- (%%parameters.[0]: string) @@>
do myType.AddMembers [ctor]
[myType]
do this.AddNamespace(ns, createTypes())
Is there any way to do what I'm trying to do when I say "base.Member" there?
If not, is there a different recommended way to store internal state in a provided type?
I have not tested this, but I think something like the following should do the trick:
ctor.InvokeCode <- fun parameters ->
<@@ let res = BaseType()
res.Member <- (%%parameters.[0]: string)
res @@>
The expression passed to InvokeCode
of a constructor does not mean the body of a constructor of a new type (if you are creating erasing type provider) - it just needs to be any expression that returns a value of the type that you are erasing to. This means that you can put more complex initialization code in the expression.
I personally prefer keeping the inline quotations simpler, so I'd have a library function:
let createBaseType (input:string) =
BaseType(Member = input)
And call the helper from a quotation:
ctor.InvokeCode <- fun parameters ->
<@@ createBaseType (%%parameters.[0]) @@>
However, this is just a matter of style - both options should work.