[CSHARP-1048] Concrete implementations of abstract members do not appear in the DeclaredMemberMaps collections as of 1.9 Created: 23/Aug/14  Updated: 09/Nov/22  Resolved: 09/Nov/22

Status: Closed
Project: C# Driver
Component/s: Serialization
Affects Version/s: 1.9.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Eli Gassert Assignee: James Kovacs
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Looks like I am having a breaking change in 1.9 up from 1.8.3.

I have an abstract base class with an “Id” property:
public abstract string Id

{ get; set; }

In my standard model, that string is given an ObjectId string representation. However, if I have a model that implements IScenario that Id stays as a unique string representation.

In 1.9, this abstract Id column does not appear in my concrete type’s DeclaredMemberMaps.

Example:

[TestClass]
public class ModelMapTests
{
public abstract class MyBase { public abstract string Id { get; set; }

}
public class MyConcrete : MyBase { public override string Id

{ get; set; }

}

public class AbstractColumnConvention : IClassMapConvention
{
public void Apply(BsonClassMap classMap)
{
if(classMap.ClassType == typeof(MyConcrete))

{ Assert.IsTrue(classMap.DeclaredMemberMaps.Any(m => m.MemberName == "Id")); }

}

public string Name
{
get

{ return "Abstract Column Convention"; }

}

}

[TestMethod]
public void ConcreteTypeHasAbstractFields()
{
var conventions = new ConventionPack();
conventions.Add(new AbstractColumnConvention());

ConventionRegistry.Register("My Conventions", conventions, t =>

{ return t.IsAssignableFrom(typeof(MyConcrete)); }

);

BsonClassMap.LookupClassMap(typeof(MyConcrete));
}
}

In 1.8.3 Id was found when mapping MyConcrete. In 1.9 it is not found in MyConcrete, which prevents me from mapping things properly (i.e. how I mapped them under 1.8.3).



 Comments   
Comment by James Kovacs [ 09/Nov/22 ]

Investigating whether this admittedly old serialization issue is still present in the 2.18.0 driver...

The root cause of the issue is that when the custom convention is run, the BsonMemberMap for the Id property has not been instantiated. Since the Id member is defined on the base class, the BsonMemberMap is instantiated when the base class is mapped, which occurs when BsonMemberMap<MyConcrete> is frozen. The BsonMemberMap for the Id property is then copied from parent to child while freezing BsonMemberMap<MyConcrete>.

This appears to have been a change in behaviour between 1.8.3 and 1.9.0. Given that the latest driver is 2.18.0, it would be a breaking change for many users to revert to the old behaviour. I'm going to close this ticket as won't fix. If anyone is having problems with the new mapping order, we request that you open a new ticket so we can investigate further.

Generated at Wed Feb 07 21:38:31 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.