Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-401

Implementing custom IdMemberConvention and ElementNameConvention

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major - P3
    • Resolution: Works as Designed
    • Affects Version/s: 1.3.1
    • Fix Version/s: 1.4
    • Component/s: Feature Request
    • Labels:
    • Environment:
      Mono 2.10.8, OS X

      Description

      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

      { get; set; }
      }

      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

      { return this._idMembers[type]; }

      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.

        Attachments

          Activity

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: