Sono nuovo in MongoDB e sto cercando di far funzionare il driver C# in serializzazione delle classi F #. Ho lavorato con l'automapper di classe usando campi mutabili F # & un costruttore senza parametri, ma in realtà ho bisogno di mantenere l'immutabilità, quindi ho iniziato a considerare l'implementazione di un IBsonSerializer per eseguire la serializzazione personalizzata. Non ho trovato alcuna documentazione per scrivere uno di questi, quindi ho appena cercato di dedurre dal codice sorgente del driver.Implementazione del serializzatore personalizzato MongoDB
Ho incontrato un problema per cui quando viene chiamato il metodo Deserialize sul serializzatore, CurrentBsonType è impostato su EndOfDocument piuttosto che sull'inizio come mi aspetto. Ho scritto l'equivalente in C# solo per assicurarmi che non si trattasse di un problema di F #, ma il problema persiste. La parte di serializzazione sembra funzionare correttamente ed è interrogabile dalla shell. Ecco il codice di esempio:
class Calendar {
public string Id { get; private set; }
public DateTime[] Holidays { get; private set; }
public Calendar(string id, DateTime[] holidays) {
Id = id;
Holidays = holidays;
}
}
class CalendarSerializer : BsonBaseSerializer {
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) {
var calendar = (Calendar) value;
bsonWriter.WriteStartDocument();
bsonWriter.WriteString("_id", calendar.Id);
bsonWriter.WriteName("holidays");
var ser = new ArraySerializer<DateTime>();
ser.Serialize(bsonWriter, typeof(DateTime[]), calendar.Holidays, null);
bsonWriter.WriteEndDocument();
}
public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options) {
if (nominalType != typeof(Calendar) || actualType != typeof(Calendar))
throw new BsonSerializationException();
if (bsonReader.CurrentBsonType != BsonType.Document)
throw new FileFormatException();
bsonReader.ReadStartDocument();
var id = bsonReader.ReadString("_id");
var ser = new ArraySerializer<DateTime>();
var holidays = (DateTime[])ser.Deserialize(bsonReader, typeof(DateTime[]), null);
bsonReader.ReadEndDocument();
return new Calendar(id, holidays);
}
public override bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) {
var calendar = (Calendar) document;
id = calendar.Id;
idNominalType = typeof (string);
idGenerator = new StringObjectIdGenerator();
return true;
}
public override void SetDocumentId(object document, object id) {
throw new NotImplementedException("SetDocumentId is not implemented");
}
}
Questo colpi con FileFormatException nel Deserialize quando il CurrentBsonType non è documento. Sto usando l'ultima versione 1.4 della fonte del driver.