Is there mongodb C# driver support System.Dynamic.DynamicObject in .NET 4?

2,853 views
Skip to first unread message

huy hoang le

unread,
Apr 19, 2012, 1:52:49 AM4/19/12
to mongodb-user
Hi,

Im working on a project that use .NET Razor and mongodb. I would like
to do something like this:

@{
var feeds = DP.Database.GetCollection("feeds").FindAll();
}

<ul>
@foreach (dynamic feed in feeds)
{
<li>@feed.message - @feed.from.name</li>
}
</ul>

However, the current mongodb C# driver FindAll() return
List<BsonDocument> which does not support dynamic object. Anybody know
a .NET 4 dynamic supported mongodb C# driver?

Thanks a lot

Nat

unread,
Apr 19, 2012, 2:12:18 AM4/19/12
to mongod...@googlegroups.com
Take a peek at http://blog.abodit.com/2011/09/dynamic-persistence-with-mongodb-look-no-classes-polymorphism-in-c/. It should give you a good starting point.
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

huy hoang le

unread,
Apr 19, 2012, 2:52:22 AM4/19/12
to mongod...@googlegroups.com, nat....@gmail.com
Thanks Nat, seem like official mongo c# driver doesnt support .NET 4

huy hoang le

unread,
Apr 19, 2012, 2:57:31 AM4/19/12
to mongod...@googlegroups.com

craiggwilson

unread,
Apr 19, 2012, 10:29:30 AM4/19/12
to mongod...@googlegroups.com

Currently, there is no support for dynamic in the MongoDB driver. This is because it is based on .NET 3.5. However, since a .NET 4.0 assembly can reference a .NET 3.5 assembly, it is possible for you to write a IBsonSerializationProvider and an IBsonSerializer in .NET 4.0 to support dynamics.

We, 10gen, are looking at doing this in the future. I have spiked some support athttps://github.com/craiggwilson/mongo-csharp-driver/tree/dynamic if you want to take a look. There are most definitely bugs, but it shows that it is possible.

huy hoang le

unread,
Apr 20, 2012, 12:44:35 AM4/20/12
to mongod...@googlegroups.com
Thanks Craigg, i just found a way to do it and it work!

Add BsonValue to inherit DynamicObject

public abstract class BsonValue : DynamicObject, IComparable<BsonValue>, IConvertible, IEquatable<BsonValue>

and then add these methods to BsonDocument to implement dynamic support:

        public override bool TryDeleteMember(DeleteMemberBinder binder)
        {
            if (binder == null)
                throw new ArgumentNullException("binder");
            if (Contains(binder.Name))
            {
                Remove(binder.Name);
                return true;
            }
            return false;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            BsonValue value;
            if (TryGetValue(binder.Name, out value))
            {
                result = value;
                return true;
            }
            result = null;
            return true;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (binder == null)
                throw new ArgumentNullException("binder");
            Set(binder.Name, BsonValue.Create(value));
            return true;
        }

        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return _indexes.Keys;
        }

Cheers!

craiggwilson

unread,
Apr 20, 2012, 8:19:48 AM4/20/12
to mongod...@googlegroups.com
Yes, that would work.  However, we cannot do this as it would mean changing our minimum supported framework from 3.5 to 4.0.  If you look at how I did it in the link I posted above, you'll find that it is fairly similar with the exception that I cannot use DynamicObject and instead have to drop lower down the stack because I'm already inheriting from BsonValue.

huy hoang le

unread,
Apr 20, 2012, 3:26:09 PM4/20/12
to mongod...@googlegroups.com
I see, thanks Craig. I think you guys should release a separate version for .NET 4

nilay

unread,
May 15, 2012, 1:13:15 AM5/15/12
to mongod...@googlegroups.com
Theoretically, it is supporting dynamic type. However, (practice) dynamic type itself conflict with BSON de-serialization,

i.e.
    public class TestClass2<T>
    {
        public MongoDB.Bson.ObjectId Id { get; set; }
        public T data { get; set; }
    }

1. Inserting with TestClass2<int> instance typed as dynamic c# variable, it will smoothly insert into mongodb as well as retrieve.

2. Now when you try to insert TestClass2<string> dynamic type, save will work but won't retrieve because of type mismatch and will fail.
Exception message: "An error occurred while deserializing the data property of class LearningPad.TestClass2`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: Input string was not in a correct format." @MongoConnection.cs Line 442

3. Only overcome is to use distinguish collections for each possible generic type (by writing some custom function that evaluate collection name runtime) but that is impracticable as you can't query them at once.  

4. I use object wrapper (that works fine) with generic promotion of fields in wrapper to make them queryable and indexable. So far that is the best solution I'm into.

Any more idea! 

Cheers!
N.
Reply all
Reply to author
Forward
0 new messages