Details
-
Bug
-
Resolution: Gone away
-
Major - P3
-
None
-
2.11.4
-
None
Description
It looks like BsonSerializer fails to resolve proper serializer for a member when declared member type doesn't match actual initialized type.
Observed code flow (might not be exact):
- BsonMemberMap looks up serializer and calls .Serialize() on found serializer (via extension method I believe).
- Matched serializer of type ClassSerializerBase<T> calls Serialize() method on base class.
Serialize() method looks up serializer on actual runtime type (e.g. value.GetType()) which fails to find serializer for a concrete type.
If you register concrete type serializer as well, driver fails with StackOverflow exception because of infinite serializer lookup loop.
Please take a look at minimal repro below.
class Program |
{
|
public class Root |
{
|
// Initialized type doesn't match declared type!!! |
public IDictionary<int, Node> Nodes { get; set; } |
= new Dictionary<int, Node>(); |
}
|
|
|
public class Node |
{
|
public string Name { get; set; } |
}
|
|
|
static void Main(string[] args) |
{
|
BsonSerializer.RegisterSerializer(typeof(IDictionary<int, Node>), |
GetInt32Serializer<Node>());
|
|
|
var root = new Root(); |
root.Nodes.Add(0, new Node { Name = "Test" }); |
|
|
using (var stringWriter = new StringWriter()) |
{
|
using (var writer = new JsonWriter(stringWriter)) |
{
|
BsonSerializer.Serialize(writer, root);
|
Console.WriteLine("Valid Root: {0}", stringWriter.ToString()); |
}
|
}
|
Console.ReadKey();
|
}
|
|
|
private static IBsonSerializer GetInt32Serializer<TValue>() |
{
|
return new DictionaryInterfaceImplementerSerializer<IDictionary<int, TValue>, int, TValue>( |
DictionaryRepresentation.Document,
|
new Int32Serializer(BsonType.String), |
BsonSerializer.SerializerRegistry.GetSerializer<TValue>());
|
}
|
}
|