[BsonKnownTypes(typeof(ChildClass1))]
|
public abstract class ParentClass
|
{
|
public string Type { get; set; }
|
}
|
|
[BsonDiscriminator("Child1")]
|
public class ChildClass1 : ParentClass
|
{
|
public ChildClass1()
|
{
|
Type = "Child1";
|
}
|
}
|
|
public class ParentClassDiscriminator : IDiscriminatorConvention
|
{
|
public string ElementName { get; } = "Type";
|
|
public Type GetActualType(IBsonReader bsonReader, Type nominalType)
|
{
|
var bookmark = bsonReader.GetBookmark();
|
|
bsonReader.ReadStartDocument();
|
if (!bsonReader.FindElement(ElementName))
|
{
|
throw new NotSupportedException($"Could not find element named: {ElementName}");
|
}
|
|
try
|
{
|
var val = bsonReader.ReadString();
|
|
|
switch (val ?? "")
|
{
|
case "Child1":
|
return typeof(ChildClass1);
|
default:
|
throw new NotSupportedException($"Could not find a Type to match type of: {val}");
|
}
|
}
|
finally
|
{
|
bsonReader.ReturnToBookmark(bookmark);
|
}
|
}
|
|
public BsonValue GetDiscriminator(Type nominalType, Type actualType)
|
{
|
if (actualType == typeof(ChildClass1))
|
{
|
return "Child1";
|
}
|
|
throw new NotImplementedException();
|
}
|
}
|
public static class Bug
|
{
|
public static void Example()
|
{
|
BsonSerializer.RegisterDiscriminatorConvention(typeof(ParentClass), new ParentClassDiscriminator());
|
|
//case 1
|
var object1 = new ChildClass1();
|
object1.ToBsonDocument();//does not throw an error
|
|
//case 2
|
ParentClass object2 = new ChildClass1();
|
object2.ToBsonDocument();//throws InvalidOperationException("Duplicate element name 'Type'.")
|
}
|
}
|