ironpython2
ironpython2 copied to clipboard
MongoDb GetCollection error: get MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
.NET6 and IronPython 2.7.11
call the function:
def cnt():
import System, clr
clr.AddReference("MongoDB.Bson")
clr.AddReference("MongoDB.Driver")
from MongoDB.Bson import *
from MongoDB.Driver import *
connStr = "....."
client = MongoClient(connStr)
database = client.GetDatabase("db")
dataset = database.GetCollection[BsonDocument]("collection")
return dataset.CountDocument(BsonDocument())
cnt()
database.GetCollection raise error:
System.InvalidOperationException: MongoDB.Driver.IMongoCollection`1[TDocument] GetCollection[TDocument](System.String, MongoDB.Driver.MongoCollectionSettings) is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
The issue appears to be something like this:
public abstract class MyBaseClass {
public abstract T GetCollection<T>();
// this is just a helper to get an instance of the internal class
public static MyBaseClass test() {
return new MyInternalClass();
}
}
internal sealed class MyInternalClass : MyBaseClass {
public override T GetCollection<T>() {
throw new NotImplementedException();
}
}
MyBaseClass.test().GetCollection[object]
which results in:
SystemError: T GetCollection[T]() is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
A possible workaround is to enable private bindings with the PrivateBinding
option.
Thanks, you are right, the code in mongodb driver is:
namespace MongoDB.Driver
{
// Token: 0x020000C0 RID: 192
internal sealed class MongoDatabaseImpl : MongoDatabaseBase
}
Internal without public....,
But how to to enable private bindings with the PrivateBinding option? Can add any paramters to the CreateEngine method?
IronPython.Hosting.Python.CreateEngine()
I modified the source code, changed the class MongoDatabaseImpl from internal to public, and recompile it.
namespace MongoDB.Driver
{
public sealed class MongoDatabaseImpl : MongoDatabaseBase
}
The GetCollection in above code run correctly, but in mongodb, there are many methods with default value as default(CancellationToken), i.e.
long CountDocuments(FilterDefinition<TDocument> filter, CountOptions options = null, CancellationToken cancellationToken = default(CancellationToken));
but in IronPython, when we call the method:
GetCollection[BsonDocument]("collection")
got
IronPython.Runtime.Exceptions.TypeErrorException: expected CancellationToken, got NoneType
I seems that IronPython does't support default value for structs, such as default(CancellationToken)
But how to to enable private bindings with the PrivateBinding option? Can add any paramters to the CreateEngine method?
You can enable private binding like this:
Python.CreateEngine(new Dictionary<string, object> { {"PrivateBinding", true} });