[CSHARP-1380] Inheriting BsonDocument Created: 13/Aug/15  Updated: 03/Dec/20  Resolved: 03/Dec/20

Status: Closed
Project: C# Driver
Component/s: BSON
Affects Version/s: 2.0.1
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: Peter Gordon Assignee: Unassigned
Resolution: Done Votes: 0
Labels: question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Can you think of a reason why creating a new class that inherits from BsonDocument would not work?

if I create this class:

public class GenericEntity : BsonDocument
{
	public GenericEntity() : base() { }
        public GenericEntity(Dictionary<string, object> dictionary) : base(dictionary) { }
        public GenericEntity(IEnumerable<KeyValuePair<string, object>> dictionary) : base(dictionary) { }
        public GenericEntity(IDictionary dictionary) : base(dictionary) { }
        public GenericEntity(IEnumerable<BsonElement> elements) : base(elements) { }
        public GenericEntity(BsonElement element) : base(element) { }
        public GenericEntity(bool allowDuplicateNames) : base(allowDuplicateNames) { }
        public GenericEntity(string name, BsonValue value) : base(name, value) { }
 
}

and then run this code:

 
var test = new Generic();
test.Add(new BsonElement("name", "test"));
test.Add(new BsonElement("db", "testdb"));
Console.Write(test.ToString());

if returns "{[{ }, { }]}" instead of the expcted "test3 = {{ "name" : "test", "db" : "testdb" }}" even though the Elements property appears to be populated properly (two elemnts each with the name an dvalue fields set properly).



 Comments   
Comment by Peter Gordon [ 13/Aug/15 ]

Makes sense - I have used this approach with some of our entities in situations where the properties need to change dynamically to good effect. What I am trying to do is slightly different though (or a little bit more than just camp (b)) - specifically related to extending an Entity with some boilerplate code. That being said, I can do that with extension methods so this is not an issue.

Comment by Craig Wilson [ 13/Aug/15 ]

Because it doesn't really make a lot of sense to do. BsonDocument can represent any structure that exists. So, the only reason to inherit is (a) to provide a different behavior (RawBsonDocument, LazyBsonDocument), or (b) to provide strongly-typed access to certain fields.

I think you're in the (b) camp. As such, inheritance is the wrong strategy. Rather, you should use composition. Have your custom class contain a field which is a BsonDocument and use it as the backing store.

class GenericEntity : IMyCustomInterface
{
  private readonly BsonDocument _backingDocument;
 
  public GenericEntity(BsonDocument document)
  {
    _backingDocument = document;
  }
 
  public string FirstName
  {
    get { return _backingDocument["firstName"].ToString(); }
    set { _backingDocument["firstName"] = value; }
  }
 
  // only if you want
  public BsonDocument BackingDocument
  {
    get { return _backingDocument; }
  }
 
  public override void ToString() 
  {
    return _backingDocument.ToString();
  }
}

This gives you a lot more flexibility, doesn't saddle you with exposing an API that you likely don't want, makes your consumers resistant to changes that we make in the BsonDocument API, etc...

Comment by Peter Gordon [ 13/Aug/15 ]

It is a little hard to explain what I am trying to do ... I'm experimenting a little. Essentially, I would like to be able to create a class that inherits from BsonDocument as well as a custom interface of mine - which would allow me to run BsonDocuments through some of my application logic that is currently dependent on structured data classes (i.e. the interface).

I was assuming that this inheritance would just work and was surprised when it didn't ... why do you think this should be disallowed?

Comment by Craig Wilson [ 13/Aug/15 ]

Perhaps you could elaborate on why you want to do this. While we haven't disallowed it, we probably should have, but that ship has sailed.

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