C# - Default discriminator convention

I am evaluating the work required to migrate from the non-official driver (samus) to the official one. I found out that the default discriminator for inheritance is the Hierarchical one, and this is kind of "hard-coded" in sonDefaultSerializer.LookupDiscriminatorConvention. Unless I am missing something, it seems that to override this, a discriminator must be set for every base type participating in serialization.

Is there a way to set the default discriminator convention to use when one is not explicitly set on a type?

If I load an entity that was persisted with the non-official driver (which uses the equivalent of the ScalarDiscriminatorConvention), will it load properly with the official driver?

And we see that the discriminators are arrays instead of scalars
because the presence of the RootClass attribute signals to use a
hierarchical discriminator.

During deserialization it actually doesn't matter whether the
discriminator is a scalar or an array. It if is an array only the last
element is used.

Given all this you may not have to set the default discriminator
convention. You probably have all the control you want just by using
or not using RootClass.

A document stored in a database using the samus driver can be loaded
successfully into an equivalent class using the official C# driver
assuming you use the same class name and property names. Or if they
differ in any way then you have to configure the class maps
appropriately.

I indeed set the the base class as the root because I wanted the "_t" entry to be serialized.

If we reuse your class hierarchy, the case I want to support is to have a collection of A instances in Mongo and be able to reload the instances from it with their nominal type. If I save the above 'c' instance in a MongoCollection<A>, although it saves all the properties of A, B and C, I cannot deal with a generic collection of A containing instances of A, B and C after loading.

Not having seen any of your code I'm not sure where you are running
into trouble, but my guess is that when you Insert or Save your
document you are not specifying the nominal type (and therefore no
discriminator is being written). Here's a short sample program that
writes an A, a B and a C to a collection and reads it back (using
discriminators and polymorphism):

I was using "collection.Save(c)", instead of "collection.Save<A>(c)". The reasons are:

- I come from the samus driver, which uses the first form.

- I assumed that since "collection" is of type "MongoCollection<A>", it would not need to be told about the type in the Save method. I understand your explanation of the technical part (compiler inference), but can you give a quick explanation of the thinking/philosophy? Why isn't the generic type of the collection used to get the nominal type?

Good thing I got this while experimenting. I am taking notes about that kind of differences between samus' driver and the official one.

I see where you're coming from. I'm hoping that someone who hadn't
used a different driver before wouldn't have the same confusion.

The thinking about why the TDefaultDocument in
MongoCollection<TDefaultDocument> is not used as the nominalType is as
follows:

- Collections in MongoDB are schemaless
- So there is no such thing as a collection of <T>, strictly speaking
- Assuming TDefaultDocument is the nominal type for a Save or Insert,
while it coincidentally might have been the right thing in your case,
would be the wrong thing if some other type of document was being
written

If you look at where TDefaultDocument is used, it is only used for
reads. For all output operations the document type, if not explicitly
stated, is inferred from the actual variable provided. This is in
keeping with collections being schema free, where the schema for each
document stored *could* be different.

The way I saw the MongoCollection<T> was more like a typed accessor/handle on an untyped collection. An accessor through which everything would be typed by T. If I would have wanted to access documents that are of another type, I would have used a collection of a different T. If I would have wanted to access all the documents that may not be of a related type, I would have used a MongoCollection<BsonDocument>.

But your explanation is clear and logic: the type T is only used for reading. With that information, I can educate my team and hope they won't forget to specify the nominal type when saving/inserting.