いくつかの実験の後、私はあなたがあなた自身の弁別子の慣習を書くことができることを知りました。理由はよくわかりませんが、デフォルトの識別子の規則では、FullNameではなくtypeクラスのNameプロパティを使用しているようです。これにより、ジェネリッククラスでは役に立たなくなります。
代わりにこのコードを使用することになりました:
class FooDiscriminatorConvention : IDiscriminatorConvention
{
public string ElementName
{
get { return "_t"; }
}
public Type GetActualType(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType)
{
if(nominalType!=typeof(MyAbstractClass))
throw new Exception("Cannot use FooDiscriminator for type " + nominalType);
var ret = nominalType;
var bookmark = bsonReader.GetBookmark();
bsonReader.ReadStartDocument();
if (bsonReader.FindElement(ElementName))
{
var value = bsonReader.ReadString();
ret = Type.GetType(value);
if(ret==null)
throw new Exception("Could not find type " + value);
if(!ret.IsSubclassOf(typeof(MyAbstractClass)))
throw new Exception("Database type does not inherit from MyAbstractClass.");
}
bsonReader.ReturnToBookmark(bookmark);
return ret;
}
public BsonValue GetDiscriminator(Type nominalType, Type actualType)
{
if (nominalType != typeof(MyAbstractClass))
throw new Exception("Cannot use FooDiscriminator for type " + nominalType);
return actualType.FullName;
}
}
そしてそれを
に登録しますBsonSerializer.RegisterDiscriminatorConvention(typeof(MyGenericClass<>), new FooDiscriminatorConvention()); //is this needed?
BsonSerializer.RegisterDiscriminatorConvention(typeof(MyAbstractClass), new FooDiscriminatorConvention());
また、「抽象クラスのインスタンスを作成できない」というエラーを回避するために、基本クラスを非抽象にする必要がありました。抽象基本クラスを持つことができればいいのですが、派生クラスは汎用であるため、BsonKnownTypesを使用できません。