Skip to content

Instantly share code, notes, and snippets.

@colinbull
Created July 2, 2013 20:39
Show Gist options
  • Save colinbull/5912890 to your computer and use it in GitHub Desktop.
Save colinbull/5912890 to your computer and use it in GitHub Desktop.
Protobuf DU serialisation
#r "System.Xml.dll"
#r "System.Runtime.Serialization.dll"
#r @"D:\Appdev\fsharp.actor\packages\protobuf-net.2.0.0.640\lib\net40\protobuf-net.dll"
#load "Library1.fs"
open ProtoBuf
open System.IO
open System.Runtime.Serialization
open Protobuf
open Microsoft.FSharp.Reflection
[<ProtoContract(SkipConstructor = true)>]
type Result =
| Success of string
| Error of string
[<CLIMutable>]
type ResultRecord = {
Id : int
Name : string
}
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof<ResultRecord>, true).Add("Id", "Name")
let cases = FSharpType.GetUnionCases(typeof<Result>)
typeof<Result>.GetNestedTypes()
|> Array.filter (fun x -> not <| x.Name.EndsWith("Tags"))
|> Array.iteri (fun i x ->
printfn "Registered %A" x.Name
let factory = FSharpValue.PreComputeUnionConstructorInfo(cases.[i])
printfn "Return type %A" factory.ReturnType
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(x, false).SetFactory(factory) |> ignore)
let serialise instance =
use ms = new MemoryStream()
Serializer.Serialize(ms, instance)
ms.ToArray()
let deserialise (bytes:byte[]) =
use ms = new MemoryStream(bytes)
Serializer.Deserialize(ms)
let du : Result =
serialise (Success "Foo")
|> deserialise
//Unfortunately I get the following exception..
//System.ArgumentException: The factory-method must return object or FSI_0006+Result+Success
//Parameter name: factory
// at ProtoBuf.Meta.RuntimeTypeModel.VerifyFactory(MethodInfo factory, Type type) in c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 1958
// at [email protected](Int32 i, Type x) in D:\Appdev\playground\Protobuf\Protobuf\Script.fsx:line 27
// at Microsoft.FSharp.Collections.ArrayModule.IterateIndexed[T](FSharpFunc`2 action, T[] array)
// at <StartupCode$FSI_0006>.$FSI_0006.main@() in D:\Appdev\playground\Protobuf\Protobuf\Script.fsx:line 21
//Stopped due to error
//Which is clear enough I just can't see how to construct a MehtodInfo that returns the correct type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment