Line data Source code
1 : #region Copyright
2 : // // -----------------------------------------------------------------------
3 : // // <copyright company="Chinchilla Software Limited">
4 : // // Copyright Chinchilla Software Limited. All rights reserved.
5 : // // </copyright>
6 : // // -----------------------------------------------------------------------
7 : #endregion
8 :
9 : using System;
10 : using System.Collections.Generic;
11 : using System.Linq;
12 : using System.Reflection;
13 : using MongoDB.Bson;
14 : using MongoDB.Bson.IO;
15 : using MongoDB.Bson.Serialization;
16 : using MongoDB.Bson.Serialization.Serializers;
17 :
18 : namespace Cqrs.MongoDB.Serialisers
19 : {
20 : /// <summary>
21 : /// A <see cref="StructSerializerBase{TValue}"/> with reasonable level support for structs.
22 : /// </summary>
23 : /// <typeparam name="TStruct">The <see cref="Type"/> of struct.</typeparam>
24 : public class BasicStructSerialiser<TStruct> : StructSerializerBase<TStruct>
25 : where TStruct : struct
26 1 : {
27 : /// <summary>
28 : /// Serializes the provide <paramref name="value"/> as a set of key/value pairs.
29 : /// </summary>
30 : /// <param name="context">The serialisation context.</param>
31 : /// <param name="args">The serialisation arguments.</param>
32 : /// <param name="value">The value.</param>
33 1 : public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TStruct value)
34 : {
35 : Type nominalType = args.NominalType;
36 : FieldInfo[] fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public);
37 : PropertyInfo[] propsAll = nominalType.GetProperties(BindingFlags.Instance | BindingFlags.Public);
38 :
39 : IEnumerable<PropertyInfo> props = propsAll.Where(prop => prop.CanWrite).ToList();
40 :
41 : IBsonWriter bsonWriter = context.Writer;
42 :
43 : bsonWriter.WriteStartDocument();
44 :
45 : foreach (FieldInfo field in fields)
46 : {
47 : bsonWriter.WriteName(field.Name);
48 : BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
49 : }
50 : foreach (PropertyInfo prop in props)
51 : {
52 : bsonWriter.WriteName(prop.Name);
53 : BsonSerializer.Serialize(bsonWriter, prop.PropertyType, prop.GetValue(value, null));
54 : }
55 :
56 : bsonWriter.WriteEndDocument();
57 : }
58 :
59 : /// <summary>
60 : /// Deserialises a value from key/value pairs.
61 : /// </summary>
62 : /// <param name="context">The deserialisation context.</param>
63 : /// <param name="args">The deserialisation arguments.</param>
64 : /// <returns>
65 : /// A deserialised value.
66 : /// </returns>
67 1 : public override TStruct Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
68 : {
69 : //boxing is required for SetValue to work
70 : var obj = (object)(new TStruct());
71 : Type actualType = args.NominalType;
72 : IBsonReader bsonReader = context.Reader;
73 :
74 : bsonReader.ReadStartDocument();
75 :
76 : while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
77 : {
78 : var name = bsonReader.ReadName();
79 :
80 : var field = actualType.GetField(name);
81 : if (field != null)
82 : {
83 : var value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
84 : field.SetValue(obj, value);
85 : }
86 :
87 : var prop = actualType.GetProperty(name);
88 : if (prop != null)
89 : {
90 : var value = BsonSerializer.Deserialize(bsonReader, prop.PropertyType);
91 : prop.SetValue(obj, value, null);
92 : }
93 : }
94 :
95 : bsonReader.ReadEndDocument();
96 :
97 : return (TStruct)obj;
98 : }
99 : }
100 : }
|