Registering a custom bson serializer changes the discriminator convention

Hello mongo community,

I have a question about some behavior I am seeing. Basically, the act of registering a custom BsonSerializer is changing discriminator behavior.

For example, say I have this code:

public class SomeClass : ISomeInterface
{

}

public interface ISomeInterface
{

}

public class SomeClassSerializer : IBsonSerializer
{
    public Type ValueType => typeof(SomeClass);

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return new SomeClass();
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        context.Writer.WriteStartDocument();
        context.Writer.WriteEndDocument();
    }
}

// The discriminator changes with or without the following line
BsonSerializer.RegisterSerializer(typeof(SomeClass), new SomeClassSerializer());

ISomeInterface item = new SomeClass();
BsonDocument doc = item.ToBsonDocument();

Console.WriteLine(doc["_t"]);

The behavior I am seeing is that if I include the line that registers the custom serializer, the discriminator looks like:
“Some.Namespace.Path.SomeClass, Some.Namespace.Path”

If I remove the line that registers the custom serializer, the discriminator looks like:
“SomeClass”

The mongo docs state that

  • “The default value for the discriminator is the name of the class (without the namespace part)”
  • " The default serializer provides two standard discriminators: ScalarDiscriminatorConvention and HierarchicalDiscriminatorConvention"
  • Serialization Tutorial

I believe what is happening based on poking around in the C# driver code on github is that when a custom serializer is registered, the ObjectDiscriminatorConvention ends up being used instead of the default Scalar or Hierarchical, and this is what is setting the disriminator to use the full namespace path.

My question is - is this intentional behavior by the mongo driver? I would like for the discriminator to remain as only “SomeClass”, as otherwise it makes the code more fragile (Ex. SomeClass may move namespaces/assembly in the future.), and I have been unable to find any documentation that states whether this is intentional or not.
What is the mongo recommended way for me to preserve the default “SomeClass” discriminator value? Am I responsible for adding a line of code to force ISomeInterface to still use the ScalarDiscriminatorConvention?

BsonSerializer.RegisterDiscriminatorConvention(typeof(ISomeInterface), new ScalarDiscriminatorConvention("_t"));

Or does this warrant raising a jira issue?

One update here - by stepping through the MongoDB.Bson code I found that I can make my custom serializer implement IBsonPolymorphicSerializer, which allows me to take control of assigning the discriminator to exacly what I want it to be inside the custom serializer. The example code from my original post would become:

public class SomeClass : ISomeInterface
{

}

public interface ISomeInterface
{

}

public class SomeClassSerializer : IBsonSerializer
{
    public Type ValueType => typeof(SomeClass);

    public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return new SomeClass();
    }

    public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
    {
        context.Writer.WriteStartDocument();
        
        var actualType = value.GetType();
        if (args.NominalType != actualType) {
            context.Writer.WriteName(TagForType); 
            context.Writer.WriteString(actualType.Name);
            context.Writer.WriteName(TagForValue); 
            context.Writer.WriteStartDocument();
        }

        // serialize "value" here...

        if (args.NominalType != actualType) {
            context.Writer.WriteEndDocument();
        }
        context.Writer.WriteEndDocument();
    }
}

BsonSerializer.RegisterSerializer(typeof(SomeClass), new SomeClassSerializer());

ISomeInterface item = new SomeClass();
BsonDocument doc = item.ToBsonDocument();

Console.WriteLine(doc["_t"]);

Is this the correct thing to do? I’m struggling to find any documentation related to IBsonPolymorphicSerializer in the serialization tutorial
https://mongodb.github.io/mongo-csharp-driver/1.11/serialization/#write-a-custom-serializer