MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Discriminadores de tipo de driver MongoDB C # com classe genérica herdando de classe base não genérica


Depois de algumas experiências, descobri que você pode escrever suas próprias convenções discriminadoras. Eu realmente não consigo entender o porquê, mas a convenção do discriminador padrão parece usar a propriedade Name da classe de tipo, em vez do FullName, o que a torna inútil para classes genéricas.

Acabei usando este código em vez disso:
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;
    }
}

E registrando-o com
BsonSerializer.RegisterDiscriminatorConvention(typeof(MyGenericClass<>), new FooDiscriminatorConvention()); //is this needed?
BsonSerializer.RegisterDiscriminatorConvention(typeof(MyAbstractClass), new FooDiscriminatorConvention());

Eu também tive que tornar a classe base não abstrata, para evitar o erro "não é possível criar instâncias de classes abstratas". Seria bom poder ter uma classe base abstrata, mas como a classe derivada é genérica, não posso usar BsonKnownTypes.