-
Type: Improvement
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: 1.3.1
-
Component/s: Feature Request
-
Environment:Mono 2.10.8, OS X
When creating multiple instances of MongoCollection<T>, each representing separate database collections, it is possible to encounter naming collisions between classes in calling into custom IdMemberConvention and ElementNameConvention classes. The following code better illustrates my point.
class A
{
ObjectId Id
}
class AB : A
{
ObjectId ABId { get; set; }
}
public class IdMemberConvention : IIdMemberConvention
{
private Dictionary<Type,string> _idMembers;
public IdMemberConvention ()
{ this._idMembers = new Dictionary<Type,string> (); }public void SetIdMember (Type type, string name)
{ this._idMembers[type] = name; } public string FindIdMember (Type type)
{
try
catch
{ return null; } }
}
For both classes A and AB I would call IdMemberConvention's SetIdMember method as follows, respectively;
SetIdMember(typeof(A), "Id");
SetIdMember(typeof(AB), "ABId");
However, this is problematic for me, as BsonClassMap calls "FindIdMember" in a recursive manner, such that the base-most class is first passed into "FindIdMember" and on up the type chain until a non-null value is returned. And so the "FindIdMember" method, in the case of type A, is called twice; first for base type System.Object and secondly for type A. Furthermore, type AB results in three calls to "FindIdMember" (assuming that the id property is not found in a base class) which are, respectively, types System.Object, A and AB. The problem arises in fetching the id member for type AB. Because AB extends class A, and I have set the id member for type A (i.e. SetIdMember(typeof(A), "Id")) as well as for type AB, "FindIdMember" would return "Id" instead of the expected "ABId".
A solution to this problem, and one I'll quickly implement for my purposes, would be to send the collection type, AB in this example, to the "FindIdMember" method, so that I could distinguish a call to "FindIdMember" between types A and AB. What do you think of this solution? Is there a cleaner way to achieve this? Is my implementation pattern here all wrong?
Thanks. I hope this is helpful.