I'm seeking community guidance regarding the cost of upgrading our existing Mongo framework to use the new 2.0 drivers.
Using the now legacy Mongo C# drivers (1.8 & 1.9), we built a framework for reading & writing our collections to MongoDB. The collections are named after specific types - for example a type of "AnimalView" is written to a collection "AnimalView".
When writing the collection, each document is accompanied by a "container" object that is typed, i.e. MongoDbContainer. "Keys" are a Guid or an object constructed using a Guid, making it pretty straightforward to do CRUD operations (with either the legacy or new Mongo drivers):
public class MongoDbContainer<TKey, TEntity> : IMongoWriter<TKey, TEntity>
{
public void Add (TKey key, TEntity entity)
{
var server = mongoClient.GetServer();
var db = server.GetDatabase(databaseName);
var collection = db.GetCollection<TEntity>(typeof(TEntity).Name);
collection.Insert(entity);
}
}
public class AnimalWriter
{
IMongoWriter<AnimalId, AnimalView> writer;
public AnimalWriter(IMongoWriter<AnimalId, AnimalView> writer)
{
this.writer = writer;
}
public void CreateAnimal(AnimalData data)
{
var view = new AnimalView {… assign from data…};
writer.Add(data.AnimalId, view);
}
}
It is apparent that this framework will be relatively straightforward to convert to the new driver. However, we also have a couple of other types of entities that we use as Indexes:
public class Singleton<T>
{
public string Id { get; set; }
public T Value { get; set; }
}
public class Chunk<T>
{
public byte Id { get; set; }
public T Value {get; private set; }
}
The "Singleton" class is written to a Mongo collection called "singletons", and is retrieved from Mongo as follows:
public MongoCollection<BsonDocument> GetSingletonsCollection()
{
var server = mongoClient.GetServer();
var db = server.GetDatabase(databaseName);
var collection = db.GetCollection("singletons");
}
This is where converting to the new driver starts to break down. The TEntity for a singleton is the type of the Singleton Value property. So to retrieve a Singleton collection for update, it is no longer sufficient to have a as the value type of the ICollection because there is no guarantee that the type TEntity will cleanly map to a BsonDocument.
Legacy Method:
public void AddSingleton(TEntity entity)
{
var collection = GetSingletonsCollection();
var singleton = new Singleton<TEntity>(entity);
collection.Insert(singleton);
}
The Legacy method did not need to know that the type of of the collection was anything more than <Singleton<BsonDocument>>
. All of the mapping and conversion was handled by the driver. However the new insert method has an issue - the collection is of type <Singleton<BsonDocument>>
, but the document to insert is a <Singleton<MyClass>>
, so
collection.InsertOneAsync(entity);
doesn't work because entity is not the same type as the collection. I have tried converting "entity" to a BsonDocument, but on some classes that conversion fails, especially when the class contains a dictionary or other types.
This problem is compounded with the "Chunk" class. Unlike singletons, Chunks are written to Mongo collections bearing the name of the "Value" property. However, the Id is a "byte" and cannot be converted to Bson as such. So in addition to the same issues with generics that we have with the Singleton class, we now have to find a way to properly map the ids.
I have tried working with reflection to create generics with some success, but am limited in what I can do, because we have to discover everything - methods and properties - via reflection. Additionally, the Builder extension methods (Filter, Update & etc) are not available (or I don't know how to use them) because they are not discoverable through reflection.
I apologize for the length of this question and lack of a specific "how-to", but it was necessary to properly describe our issues. We would like to upgrade to MongoDB.Driver 2.0, but the cost may be prohibitive given the amount of rewrite we may have to do. And while staying with the legacy 1.x drivers is attractive because it continues to work, we are worried about their being desupported, in addition to not being able to take advantage of new features introduced in Mongo going forward.
Is it premature to upgrade to MongoDB 3.0 and use the 2.0 drivers (are further API changes in the works or is what is baked into 2.0 pretty firm at this point)? Am I misguided in my approach of trying to keep our existing, non-generic framework in place?
Thank you very much in advance for any direction we can provide.