Search code examples
c#mongodb-.net-driver

Have types always get saved with a discriminator without applying [BsonDiscriminator(Required = true)] attribute to each class


It is possible to force the MongoDB.Driver to save a discriminator for a specific type by applying the [BsonDiscriminator(Required = true)] attribute.

For example:

[BsonDiscriminator(Required = true)]
public class MyClass
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
}

Resulting in this json:

{
    "_id" : ObjectId("5b3caf1bed2891065c972547"),
    "_t" : "MyClass"
}

Now my question:
Is it possible to configure the MongoDB.Driver to always save the Discriminator for each type without explicitly applying the [BsonDiscriminator(Required = true)] attribute on each class?

Edit:
One possibility would be to derive all entities from a base class which has the [BsonDiscriminator(Required = true)] attribute set. But I would rather prefer not to do this, to avoid having my entities to know too much about the persistence mechanism used.


Solution

  • The solution I came up with is creating and registering a custom ClassMapConvention (MongoDB Conventions).

    First we are creating a ConventionPack and adding our ClassMapConvention to it:

    var pack = new ConventionPack();
    pack.AddClassMapConvention("AlwaysApplyDiscriminator", m => m.SetDiscriminatorIsRequired(true));
    

    After creating the ConventionPack we just have to register it to the ConventionRegistry like this:

    ConventionRegistry.Register("CustomConventions", pack, t => true);
    

    Note
    The convention must be registered before any call to the MongoDB Api.


    Now every object that gets saved to the DB, gets saved with an additional Type _t attribute (without the need of explicitly adding the [BsonDiscriminator(Required = true)] attribute on class level):

    {
        "_id" : ObjectId("5b3caf1bed2891065c972547"),
        "_t" : "MyClass"
    }