StructBsonSerialize.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Reflection;
  4. using MongoDB.Bson;
  5. using MongoDB.Bson.IO;
  6. using MongoDB.Bson.Serialization;
  7. using MongoDB.Bson.Serialization.Serializers;
  8. namespace ET
  9. {
  10. public class StructBsonSerialize<TValue> : StructSerializerBase<TValue> where TValue : struct
  11. {
  12. private readonly List<PropertyInfo> propertyInfo = new List<PropertyInfo>();
  13. public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value)
  14. {
  15. Type nominalType = args.NominalType;
  16. var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public);
  17. var propsAll = nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
  18. propertyInfo.Clear();
  19. foreach (var prop in propsAll)
  20. {
  21. if (prop.CanWrite)
  22. {
  23. propertyInfo.Add(prop);
  24. }
  25. }
  26. var bsonWriter = context.Writer;
  27. bsonWriter.WriteStartDocument();
  28. foreach (var field in fields)
  29. {
  30. bsonWriter.WriteName(field.Name);
  31. BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
  32. }
  33. foreach (var prop in propertyInfo)
  34. {
  35. bsonWriter.WriteName(prop.Name);
  36. BsonSerializer.Serialize(bsonWriter, prop.PropertyType, prop.GetValue(value, null));
  37. }
  38. bsonWriter.WriteEndDocument();
  39. }
  40. public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
  41. {
  42. //boxing is required for SetValue to work
  43. var obj = (object)(new TValue());
  44. var actualType = args.NominalType;
  45. var bsonReader = context.Reader;
  46. bsonReader.ReadStartDocument();
  47. while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
  48. {
  49. var name = bsonReader.ReadName(Utf8NameDecoder.Instance);
  50. var field = actualType.GetField(name);
  51. if (field != null)
  52. {
  53. var value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
  54. field.SetValue(obj, value);
  55. }
  56. var prop = actualType.GetProperty(name);
  57. if (prop != null)
  58. {
  59. var value = BsonSerializer.Deserialize(bsonReader, prop.PropertyType);
  60. prop.SetValue(obj, value, null);
  61. }
  62. }
  63. bsonReader.ReadEndDocument();
  64. return (TValue)obj;
  65. }
  66. }
  67. }