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);