I'm trying to use Microsoft Bond to serialize nested objects. But Bond throws internal errors (such KeyNotFoundException).
My classes:
interface IFoo
{
}
[Bond.Schema]
class Foo1 : IFoo
{
[Bond.Id(0)]
public string Foo1Field { get; set; }
}
[Bond.Schema]
class Bar
{
[Bond.Id(0)]
public IFoo SomeFooInstance { get; set; }
}
Then I create an instance and serialize:
var src = new Bar() { SomeFooInstance = new Foo1() { Foo1Field = "Str" }};
var output = new OutputBuffer();
var writer = new CompactBinaryWriter<OutputBuffer>(output);
Serialize.To(writer, src);
var input = new InputBuffer(output.Data);
var reader = new CompactBinaryReader<InputBuffer>(input);
var dst = Deserialize<Bar>.From(reader);
But I'm getting exceptions (such KeyNotFoundException) at Serialize.To(writer, src);.
I also tried to add [Bond.Schema] to IFoo, but then the Deserialize<Bar>.From(reader); fails...
How can I serialize Bar class that contains some Foo class with Bond without getting exceptions like that?
If you want to use interfaces with behavioral differences (and not structural differences), the trick is to provide the deserializer with a factory so that it knows how to create a concrete instance of
IFoowhen it needs to. Notice that the implementations do not have the the[Bond.Schema]attribute, as they both implement theIFooschema.If you need both behavioral and structural differences, then you'll need to pair this with polymorphism and a
bonded<IFoo>field so that you can delay deserialization until you have enough type information to select the proper implementation. (Polymorphism is explicit and opt-in in Bond.)I'd show an example of this, but while writing up this answer on 2018-02-21, I found a bug in the handling of classes with
[Bond.Schema]that implement interfaces with[Bond.Schema]: the fields from the interface are omitted.For now, the workaround would be to use inheritance with classes and use virtual properties. For example:
This prints: