Skip to content

Commit d66bce7

Browse files
author
rstam
committed
Finished work on CSHARP-284/308. Added support for itemSerializationOptions to legacy and generic versions of EnumerableSerializer, QueueSerializer and StackSerializer.
1 parent 410ecc3 commit d66bce7

File tree

6 files changed

+348
-16
lines changed

6 files changed

+348
-16
lines changed

Bson/Serialization/Options/ArraySerializationOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
using System.Text;
2020

2121
using MongoDB.Bson.Serialization.Attributes;
22+
using MongoDB.Bson.Serialization.Serializers;
2223

2324
namespace MongoDB.Bson.Serialization.Options
2425
{
@@ -74,6 +75,15 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
7475
if (_itemSerializationOptions == null)
7576
{
7677
var itemDefaultSerializationOptions = itemSerializer.GetDefaultSerializationOptions();
78+
79+
// special case for legacy collections: allow BsonRepresentation on object
80+
if (itemDefaultSerializationOptions == null &&
81+
(serializer.GetType() == typeof(EnumerableSerializer) || serializer.GetType() == typeof(QueueSerializer) || serializer.GetType() == typeof(StackSerializer)) &&
82+
attribute.GetType() == typeof(BsonRepresentationAttribute))
83+
{
84+
itemDefaultSerializationOptions = new RepresentationSerializationOptions(BsonType.Null); // will be modified later by ApplyAttribute
85+
}
86+
7787
if (itemDefaultSerializationOptions == null)
7888
{
7989
var message = string.Format(
@@ -83,6 +93,7 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
8393
BsonUtils.GetFriendlyTypeName(itemSerializer.GetType()));
8494
throw new NotSupportedException(message);
8595
}
96+
8697
_itemSerializationOptions = itemDefaultSerializationOptions.Clone();
8798
}
8899
_itemSerializationOptions.ApplyAttribute(itemSerializer, attribute);

Bson/Serialization/Options/DictionarySerializationOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
210210
BsonUtils.GetFriendlyTypeName(itemSerializer.GetType()));
211211
throw new NotSupportedException(message);
212212
}
213+
213214
_itemSerializationOptions = itemDefaultSerializationOptions.Clone();
214215
}
215216

Bson/Serialization/Serializers/CollectionGenericSerializers.cs

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
using MongoDB.Bson.IO;
2424
using MongoDB.Bson.Serialization;
25+
using MongoDB.Bson.Serialization.Options;
2526

2627
namespace MongoDB.Bson.Serialization.Serializers
2728
{
@@ -36,6 +37,7 @@ public class EnumerableSerializer<T> : BsonBaseSerializer
3637
/// Initializes a new instance of the EnumerableSerializer class.
3738
/// </summary>
3839
public EnumerableSerializer()
40+
: base(new ArraySerializationOptions())
3941
{
4042
}
4143

@@ -114,10 +116,14 @@ public override void Serialize(
114116
}
115117
else
116118
{
119+
var items = (IEnumerable<T>)value;
120+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
121+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
122+
117123
bsonWriter.WriteStartArray();
118-
foreach (var element in (IEnumerable<T>)value)
124+
foreach (var item in items)
119125
{
120-
BsonSerializer.Serialize(bsonWriter, typeof(T), element);
126+
BsonSerializer.Serialize(bsonWriter, typeof(T), item, itemSerializationOptions);
121127
}
122128
bsonWriter.WriteEndArray();
123129
}
@@ -135,6 +141,7 @@ public class QueueSerializer<T> : BsonBaseSerializer
135141
/// Initializes a new instance of the QueueSerializer class.
136142
/// </summary>
137143
public QueueSerializer()
144+
: base(new ArraySerializationOptions())
138145
{
139146
}
140147

@@ -181,6 +188,19 @@ public override object Deserialize(
181188
}
182189
}
183190

191+
/// <summary>
192+
/// Gets the serialization info for individual items of an enumerable type.
193+
/// </summary>
194+
/// <returns>The serialization info for the items.</returns>
195+
public override BsonSerializationInfo GetItemSerializationInfo()
196+
{
197+
string elementName = null;
198+
var serializer = BsonSerializer.LookupSerializer(typeof(T));
199+
var nominalType = typeof(T);
200+
IBsonSerializationOptions serializationOptions = null;
201+
return new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);
202+
}
203+
184204
/// <summary>
185205
/// Serializes an object to a BsonWriter.
186206
/// </summary>
@@ -200,10 +220,14 @@ public override void Serialize(
200220
}
201221
else
202222
{
223+
var items = (Queue<T>)value;
224+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
225+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
226+
203227
bsonWriter.WriteStartArray();
204-
foreach (var element in (Queue<T>)value)
228+
foreach (var item in items)
205229
{
206-
BsonSerializer.Serialize(bsonWriter, typeof(T), element);
230+
BsonSerializer.Serialize(bsonWriter, typeof(T), item, itemSerializationOptions);
207231
}
208232
bsonWriter.WriteEndArray();
209233
}
@@ -221,6 +245,7 @@ public class StackSerializer<T> : BsonBaseSerializer
221245
/// Initializes a new instance of the StackSerializer class.
222246
/// </summary>
223247
public StackSerializer()
248+
: base(new ArraySerializationOptions())
224249
{
225250
}
226251

@@ -267,6 +292,19 @@ public override object Deserialize(
267292
}
268293
}
269294

295+
/// <summary>
296+
/// Gets the serialization info for individual items of an enumerable type.
297+
/// </summary>
298+
/// <returns>The serialization info for the items.</returns>
299+
public override BsonSerializationInfo GetItemSerializationInfo()
300+
{
301+
string elementName = null;
302+
var serializer = BsonSerializer.LookupSerializer(typeof(T));
303+
var nominalType = typeof(T);
304+
IBsonSerializationOptions serializationOptions = null;
305+
return new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);
306+
}
307+
270308
/// <summary>
271309
/// Serializes an object to a BsonWriter.
272310
/// </summary>
@@ -286,12 +324,15 @@ public override void Serialize(
286324
}
287325
else
288326
{
327+
var items = ((Stack<T>)value).ToArray(); // convert to array to allow efficient access in reverse order
328+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
329+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
330+
331+
// serialize first pushed item first (reverse of enumeration order)
289332
bsonWriter.WriteStartArray();
290-
var outputOrder = new List<T>((Stack<T>)value); // serialize first pushed item first (reverse of enumerator order)
291-
outputOrder.Reverse();
292-
foreach (var element in outputOrder)
333+
for (var i = items.Length - 1; i >= 0; i--)
293334
{
294-
BsonSerializer.Serialize(bsonWriter, typeof(T), element);
335+
BsonSerializer.Serialize(bsonWriter, typeof(T), items[i], itemSerializationOptions);
295336
}
296337
bsonWriter.WriteEndArray();
297338
}

Bson/Serialization/Serializers/CollectionSerializers.cs

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
using MongoDB.Bson.IO;
2424
using MongoDB.Bson.Serialization;
25+
using MongoDB.Bson.Serialization.Options;
2526

2627
namespace MongoDB.Bson.Serialization.Serializers
2728
{
@@ -38,6 +39,7 @@ public class EnumerableSerializer : BsonBaseSerializer
3839
/// Initializes a new instance of the EnumerableSerializer class.
3940
/// </summary>
4041
public EnumerableSerializer()
42+
: base(new ArraySerializationOptions())
4143
{
4244
}
4345

@@ -93,6 +95,19 @@ public override object Deserialize(
9395
}
9496
}
9597

98+
/// <summary>
99+
/// Gets the serialization info for individual items of an enumerable type.
100+
/// </summary>
101+
/// <returns>The serialization info for the items.</returns>
102+
public override BsonSerializationInfo GetItemSerializationInfo()
103+
{
104+
string elementName = null;
105+
var serializer = BsonSerializer.LookupSerializer(typeof(object));
106+
var nominalType = typeof(object);
107+
IBsonSerializationOptions serializationOptions = null;
108+
return new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);
109+
}
110+
96111
/// <summary>
97112
/// Serializes an object to a BsonWriter.
98113
/// </summary>
@@ -112,10 +127,14 @@ public override void Serialize(
112127
}
113128
else
114129
{
130+
var items = (IEnumerable)value;
131+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
132+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
133+
115134
bsonWriter.WriteStartArray();
116-
foreach (var element in (IEnumerable)value)
135+
foreach (var item in items)
117136
{
118-
BsonSerializer.Serialize(bsonWriter, typeof(object), element);
137+
BsonSerializer.Serialize(bsonWriter, typeof(object), item, itemSerializationOptions);
119138
}
120139
bsonWriter.WriteEndArray();
121140
}
@@ -135,6 +154,7 @@ public class QueueSerializer : BsonBaseSerializer
135154
/// Initializes a new instance of the QueueSerializer class.
136155
/// </summary>
137156
public QueueSerializer()
157+
: base(new ArraySerializationOptions())
138158
{
139159
}
140160

@@ -190,6 +210,19 @@ public override object Deserialize(
190210
}
191211
}
192212

213+
/// <summary>
214+
/// Gets the serialization info for individual items of an enumerable type.
215+
/// </summary>
216+
/// <returns>The serialization info for the items.</returns>
217+
public override BsonSerializationInfo GetItemSerializationInfo()
218+
{
219+
string elementName = null;
220+
var serializer = BsonSerializer.LookupSerializer(typeof(object));
221+
var nominalType = typeof(object);
222+
IBsonSerializationOptions serializationOptions = null;
223+
return new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);
224+
}
225+
193226
/// <summary>
194227
/// Serializes an object to a BsonWriter.
195228
/// </summary>
@@ -209,10 +242,14 @@ public override void Serialize(
209242
}
210243
else
211244
{
245+
var items = (Queue)value;
246+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
247+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
248+
212249
bsonWriter.WriteStartArray();
213-
foreach (var element in (Queue)value)
250+
foreach (var item in items)
214251
{
215-
BsonSerializer.Serialize(bsonWriter, typeof(object), element);
252+
BsonSerializer.Serialize(bsonWriter, typeof(object), item, itemSerializationOptions);
216253
}
217254
bsonWriter.WriteEndArray();
218255
}
@@ -232,6 +269,7 @@ public class StackSerializer : BsonBaseSerializer
232269
/// Initializes a new instance of the StackSerializer class.
233270
/// </summary>
234271
public StackSerializer()
272+
: base(new ArraySerializationOptions())
235273
{
236274
}
237275

@@ -287,6 +325,19 @@ public override object Deserialize(
287325
}
288326
}
289327

328+
/// <summary>
329+
/// Gets the serialization info for individual items of an enumerable type.
330+
/// </summary>
331+
/// <returns>The serialization info for the items.</returns>
332+
public override BsonSerializationInfo GetItemSerializationInfo()
333+
{
334+
string elementName = null;
335+
var serializer = BsonSerializer.LookupSerializer(typeof(object));
336+
var nominalType = typeof(object);
337+
IBsonSerializationOptions serializationOptions = null;
338+
return new BsonSerializationInfo(elementName, serializer, nominalType, serializationOptions);
339+
}
340+
290341
/// <summary>
291342
/// Serializes an object to a BsonWriter.
292343
/// </summary>
@@ -306,12 +357,15 @@ public override void Serialize(
306357
}
307358
else
308359
{
360+
var items = ((Stack)value).ToArray(); // convert to array to allow efficient access in reverse order
361+
var arraySerializationOptions = EnsureSerializationOptions<ArraySerializationOptions>(options);
362+
var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions;
363+
364+
// serialize first pushed item first (reverse of enumeration order)
309365
bsonWriter.WriteStartArray();
310-
var outputOrder = new ArrayList((Stack)value); // serialize first pushed item first (reverse of enumerator order)
311-
outputOrder.Reverse();
312-
foreach (var element in outputOrder)
366+
for (var i = items.Length - 1; i >= 0; i--)
313367
{
314-
BsonSerializer.Serialize(bsonWriter, typeof(object), element);
368+
BsonSerializer.Serialize(bsonWriter, typeof(object), items[i], itemSerializationOptions);
315369
}
316370
bsonWriter.WriteEndArray();
317371
}

0 commit comments

Comments
 (0)