在 MongoDb + C# 中反序列化没有默认构造函数的对象

Meh*_*ran 2 c# mongodb bson mongodb-.net-driver

考虑两个类:

public class Entity
{
    public ObjectId Id { get; set; }
    public E2 e = new E2(ConfigClass.SomeStaticMethod());
}

public class E2
{
    [BsonIgnore]
    public int counter = 5;
    public DateTime last_update { get; set; }

    public E2(int c)
    {
        counter = c;
    }
}
Run Code Online (Sandbox Code Playgroud)

Entity我将像这样向 MongoDb存储然后检索类型的对象(假设集合为空):

var collection = database.GetCollection<Entity>("temp");
collection.Save<Entity>(new Entity());
var list = collection.FindAs<Entity>(new QueryDocument());
var ent = list.Single();
Run Code Online (Sandbox Code Playgroud)

无论ConfigClass.SomeStaticMethod()返回什么,该counter字段都将为零(整数的默认值)。但是如果我向类添加默认构造函数,E2那么counter将会是5.

这意味着 MongoDb 的 C# 驱动程序在调用非默认构造函数时出现问题(这是完全可以理解的)。我知道BsonDefaultValueBSON 库中定义了一个属性,但它只能接受constant expressions.

我想做的是从配置文件中加载字段的默认值,同时从 MongoDb 检索对象的其余部分!?当然是用最少的努力。

[更新]

我也对此进行了测试,结果相同:

public class Entity
{
    public ObjectId Id { get; set; }
    public E2 e = new E2();
    public Entity()
    {
        e.counter = ConfigClass.SomeStaticMethod();
    }
}

public class E2
{
    [BsonIgnore]
    public int counter = 5;
    public DateTime last_update { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

运行此代码结果counter再次为零!

Meh*_*ran 5

我设法像这样完成它:

public class Entity
{
    public ObjectId Id { get; set; }
    public E2 e = new E2();
}

public class E2 : ISupportInitialize
{
    [BsonIgnore]
    public int counter = 5;
    public DateTime last_update { get; set; }

    public void BeginInit()
    {
    }

    public void EndInit()
    {
        counter = ConfigClass.SomeStaticMethod();
    }
}
Run Code Online (Sandbox Code Playgroud)

ISupportInitialize接口提供了BeginInit和两个方法EndInit,分别在反序列化过程之前和之后调用。它们是设置默认值的最佳位置。