Tuesday, June 12, 2012

Generic Invoke function for Type provider with get / set features

A customer is using the SQL type provider access different databases. He then want to write an general function to access these types. It is not easy to give an interface to the generated types. So he resort to some generic methods, so can save his coding effort. What he want a function can get and set the value of a property on the parameter. The parameter might have different types because they are from different data source, but all of them have the same proeprty/method.

If you still remember the GI function, which makes cat and dog walk together, in my Channel 9 video. You can apply the GI function here.

The following is the sample code. (delete extra space if the code cannot compile)


let inline get2< ^a when ^a : (member get_Name  : unit -> string ) and
                                 ^a : (member setValue : string * string -> unit)>
 xItem =
  let name =  (^a : (member get_Name  : unit -> string ) xItem)
  let value = (^a : (member setValue : string * string -> unit) (xItem, "123_2", "123_2" ))
  name, value

// pretend this is the type from type provider
type MyClass() = class
    member val Name = "" with get, set
    member public this.setValue(str0:string, str1:string) = this.Name <- sprintf "%s, %s" str0 str1
end

// pretend this is the type from type provider
type MyClass2() = class
    member val Name = "" with get, set
    member public this.setValue(str0:string, str1:string) = this.Name <- sprintf "%s, %s" str0 str1
end

[< EntryPoint >]
let main argv =

    let a0 = MyClass()
    let a1 = MyClass2()

    get(a0)
    get2(a1)

    printfn "%s" a0.Name   // the value is "123, 123"
    printfn "%s" a1.Name   // the value is "123_2, 123_2"
 
    printfn "%A" argv
    0 // return an integer exit code

No comments: