Home > Net >  Mongodb C# - Registering class maps with generics works, where using types fails
Mongodb C# - Registering class maps with generics works, where using types fails

Time:07-21

I have a collection of objects, and each object has a property, EventData, that is many different types. These types all inherit from an IEventData interface.

For example:

{ _id: '...', EventData: { _t: 'TypeA', ... } }
{ _id: '...', EventData: { _t: 'TypeB', ... } }

I'm currently facing an issue with the MongoDB C# driver when trying to register class maps. When using the generic version to register the class map, the EventData object is correctly serialised with all properties and the type discriminator:

BsonClassMap.RegisterClassMap<TypeA>();
// Full event data is written to collection
// { _id: '...', EventData: { _t: 'TypeA', InterfaceProperty: '...', ClassProperty: '...' } }

This works fine, however I have a large amount of different event types, and want to try and use some reflection to help automate this. When trying to use the non-generic version of the RegisterClassMap whilst iterating over all types that implement the IEventData interface, only the interface members are serialised:

var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(i => i.GetTypes())
.Where(t => typeof(IEventData).IsAssignableFrom(t));

foreach (var type in types)
{
    // If it's an interface, skip as we can't register those
    if (type.IsInterface)
        continue;
        
    if (!BsonClassMap.IsClassMapRegistered(type))
       BsonClassMap.RegisterClassMap(new BsonClassMap(type));
        
 }

// Only the interface properties are written to collection
// { _id: '...', EventData: { _t: 'TypeA', InterfaceProperty: '...' } }

Is there some property or something I'm missing to set when using the non-generic type to register the class maps that allow the full type to stored in the collection?

Thanks Justin

CodePudding user response:

The difference between the two variants is that in case of RegisterClassMap<T>() a call to AutoMap is included. In order to harmonize your reflection based approach with the call of the generic version, you can add the call to AutoMap:

var cm = new BsonClassMap(type);
cm.AutoMap();
BsonClassMap.RegisterClassMap(cm);
  • Related