Reputation: 12117
I have a type:
type T =
{
a: int
b: string
}
and an array of type T called 'myArray'.
and I want to serialize myArray with FSPickler:
FsPickler.CreateBinarySerializer().Pickle myArray
but in the pickle file, the type T is fully qualified and if I relocate it to another app/namespace, then the unpickle fails.
I asked on the FSPickler git but the answer I received is:
Per documentation in http://mbraceproject.github.io/FsPickler/ the serializer is not > designed with version tolerance in mind. That being said, it should be possible to work > around that issue by providing a custom implementation of the ITypeNameConverter interface.
ok, fair enough.
However, the documentation is providing examples clearly written by someone that knows picklers in general and geared toward other people that know picklers as well.
Can anyone post an example where I could make a custom serializer / deserializer for this basic case? From the docs, I see all the odd cases explained with the assumption that the reader knows how to make a basic serializer with FSPickler.
Or, maybe I missed something terribly obvious in the doc and I'd gladly recognize it if I saw it :)
The doc is here: https://mbraceproject.github.io/FsPickler/tutorial.html
and, for context, I'm going through 24 GB of data (with a type more complex than in this example obviously), so SPEED is everything and FSPickler seems quite fast.
Upvotes: 3
Views: 149
Reputation: 17068
There doesn't seem to be any documentation on this at all, but I managed to hack together something that works. The trick I found is to use a very simple converter that always uses the same type name, like this:
let converter =
{
new ITypeNameConverter with
member this.OfSerializedType(typeInfo) =
{ typeInfo with Name = "dummy" } // always use dummy type name
member this.ToDeserializedType(typeInfo) =
typeInfo
}
We can then pickle an array of T
s like this:
type T =
{
a: int
b: string
}
let tArray =
[|
{ a = 1; b = "one" }
{ a = 2; b = "two" }
{ a = 3; b = "three" }
|]
let serializer = FsPickler.CreateBinarySerializer(typeConverter = converter)
let bytes = serializer.Pickle(tArray)
And then we can unpickle it to an array of a different type that has the same structure ("duck typing"):
type U =
{
a: int
b: string
}
let uArray = serializer.UnPickle<U[]>(bytes)
I have no idea if this is the "right" way to do it. I found that ITypeNameConverter
didn't behave like I expected. In particular, it seems that OfSerializedType
is called during both pickling and unpickling, while ToDeserializedType
isn't called at all. Maybe I'm missing something important.
Upvotes: 3