using System; using System.Collections.Generic; using System.Reflection; using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; namespace ET { public class StructBsonSerialize : StructSerializerBase where TValue : struct { private readonly List propertyInfo = new List(); public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value) { Type nominalType = args.NominalType; var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public); var propsAll = nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public); propertyInfo.Clear(); foreach (PropertyInfo prop in propsAll) { if (prop.CanWrite) { if (!prop.Name.Equals("Item", StringComparison.OrdinalIgnoreCase)) propertyInfo.Add(prop); } } IBsonWriter bsonWriter = context.Writer; bsonWriter.WriteStartDocument(); foreach (FieldInfo field in fields) { bsonWriter.WriteName(field.Name); BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value)); } foreach (PropertyInfo prop in propertyInfo) { bsonWriter.WriteName(prop.Name); BsonSerializer.Serialize(bsonWriter, prop.PropertyType, prop.GetValue(value, null)); } bsonWriter.WriteEndDocument(); } public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { //boxing is required for SetValue to work object obj = (object)(new TValue()); Type actualType = args.NominalType; IBsonReader bsonReader = context.Reader; bsonReader.ReadStartDocument(); while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) { string name = bsonReader.ReadName(Utf8NameDecoder.Instance); FieldInfo field = actualType.GetField(name); if (field != null) { object value = BsonSerializer.Deserialize(bsonReader, field.FieldType); field.SetValue(obj, value); } PropertyInfo prop = actualType.GetProperty(name); if (prop != null) { object value = BsonSerializer.Deserialize(bsonReader, prop.PropertyType); prop.SetValue(obj, value, null); } } bsonReader.ReadEndDocument(); return (TValue)obj; } } }