Berikut adalah contoh serializer untuk System.Type yang membuat serial nama Type sebagai string BSON. Ini memiliki beberapa keterbatasan karena metode Deserialize gagal jika nama tipenya bukan tipe sistem atau dalam Majelis yang sama, tetapi Anda dapat mengubah serializer sampel ini untuk menulis AssemblyQualifiedName sebagai gantinya.
public class TypeSerializer : IBsonSerializer
{
public object Deserialize(BsonReader reader, Type nominalType, IBsonSerializationOptions options)
{
var actualType = nominalType;
return Deserialize(reader, nominalType, actualType, options);
}
public object Deserialize(BsonReader reader, Type nominalType, Type actualType, IBsonSerializationOptions options)
{
if (reader.CurrentBsonType == BsonType.Null)
{
return null;
}
else
{
var fullName = reader.ReadString();
return Type.GetType(fullName);
}
}
public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator)
{
throw new InvalidOperationException();
}
public void Serialize(BsonWriter writer, Type nominalType, object value, IBsonSerializationOptions options)
{
if (value == null)
{
writer.WriteNull();
}
else
{
writer.WriteString(((Type)value).FullName);
}
}
public void SetDocumentId(object document, object id)
{
throw new InvalidOperationException();
}
}
Triknya adalah mendaftarkannya dengan benar. Anda perlu mendaftarkannya untuk System.Type dan System.RuntimeType, tetapi System.RuntimeType tidak bersifat publik sehingga Anda tidak dapat merujuknya dalam kode Anda. Tapi Anda bisa mendapatkannya menggunakan Type.GetType. Berikut kode untuk mendaftarkan serializer:
var typeSerializer = new TypeSerializer();
BsonSerializer.RegisterSerializer(typeof(Type), typeSerializer);
BsonSerializer.RegisterSerializer(Type.GetType("System.RuntimeType"), typeSerializer);
Saya menggunakan loop pengujian ini untuk memverifikasi bahwa itu berhasil:
var types = new Type[] { typeof(int), typeof(string), typeof(Guid), typeof(C) };
foreach (var type in types)
{
var json = type.ToJson();
Console.WriteLine(json);
var rehydratedType = BsonSerializer.Deserialize<Type>(json);
Console.WriteLine("{0} -> {1}", type.FullName, rehydratedType.FullName);
}
di mana C hanyalah kelas kosong:
public static class C
{
}