Skip to content

Commit 56c9ee8

Browse files
rstamcraiggwilson
authored andcommitted
More work on CSHARP-460. Added KeyValueSerializationOptions to DictionarySerializationOptions.
1 parent 88c5eed commit 56c9ee8

File tree

3 files changed

+78
-46
lines changed

3 files changed

+78
-46
lines changed

Bson/Serialization/Options/DictionarySerializationOptions.cs

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,15 @@ public class DictionarySerializationOptions : BsonBaseSerializationOptions
5858

5959
// private fields
6060
private DictionaryRepresentation _representation = DictionaryRepresentation.Dynamic;
61-
private IBsonSerializationOptions _valueSerializationOptions;
61+
private KeyValuePairSerializationOptions _keyValuePairSerializationOptions;
6262

6363
// constructors
6464
/// <summary>
6565
/// Initializes a new instance of the DictionarySerializationOptions class.
6666
/// </summary>
6767
public DictionarySerializationOptions()
6868
{
69+
_keyValuePairSerializationOptions = (KeyValuePairSerializationOptions)KeyValuePairSerializationOptions.Defaults.Clone();
6970
}
7071

7172
/// <summary>
@@ -75,17 +76,22 @@ public DictionarySerializationOptions()
7576
public DictionarySerializationOptions(DictionaryRepresentation representation)
7677
{
7778
_representation = representation;
79+
_keyValuePairSerializationOptions = (KeyValuePairSerializationOptions)KeyValuePairSerializationOptions.Defaults.Clone();
7880
}
7981

8082
/// <summary>
8183
/// Initializes a new instance of the DictionarySerializationOptions class.
8284
/// </summary>
8385
/// <param name="representation">The representation to use for a Dictionary.</param>
84-
/// <param name="valueSerializationOptions">The serialization options for the values in the dictionary.</param>
85-
public DictionarySerializationOptions(DictionaryRepresentation representation, IBsonSerializationOptions valueSerializationOptions)
86+
/// <param name="keyValuePairSerializationOptions">The serialization options for the key/value pairs in the dictionary.</param>
87+
public DictionarySerializationOptions(DictionaryRepresentation representation, KeyValuePairSerializationOptions keyValuePairSerializationOptions)
8688
{
89+
if (keyValuePairSerializationOptions == null)
90+
{
91+
throw new ArgumentNullException("keyValuePairSerializationOptions");
92+
}
8793
_representation = representation;
88-
_valueSerializationOptions = valueSerializationOptions;
94+
_keyValuePairSerializationOptions = keyValuePairSerializationOptions;
8995
}
9096

9197
// public static properties
@@ -111,7 +117,13 @@ public static DictionarySerializationOptions ArrayOfDocuments
111117
public static DictionarySerializationOptions Defaults
112118
{
113119
get { return __defaults; }
114-
set { __defaults = value; }
120+
set {
121+
if (value == null)
122+
{
123+
throw new ArgumentNullException("value");
124+
}
125+
__defaults = value;
126+
}
115127
}
116128

117129
/// <summary>
@@ -134,11 +146,20 @@ public static DictionarySerializationOptions Dynamic
134146
/// <summary>
135147
/// Gets or sets the serialization options for the values in the dictionary.
136148
/// </summary>
137-
[Obsolete("Use ValueSerializationOptions instead.")]
149+
[Obsolete("Use KeyValuePairSerializationOptions instead.")]
138150
public IBsonSerializationOptions ItemSerializationOptions
139151
{
140-
get { return ValueSerializationOptions; }
141-
set { ValueSerializationOptions = value; }
152+
get { return _keyValuePairSerializationOptions.ValueSerializationOptions; }
153+
set {
154+
if (value == null)
155+
{
156+
throw new ArgumentNullException("value");
157+
}
158+
_keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
159+
_keyValuePairSerializationOptions.Representation,
160+
_keyValuePairSerializationOptions.KeySerializationOptions,
161+
value);
162+
}
142163
}
143164

144165
/// <summary>
@@ -157,13 +178,17 @@ public DictionaryRepresentation Representation
157178
/// <summary>
158179
/// Gets or sets the serialization options for the values in the dictionary.
159180
/// </summary>
160-
public IBsonSerializationOptions ValueSerializationOptions
181+
public KeyValuePairSerializationOptions KeyValuePairSerializationOptions
161182
{
162-
get { return _valueSerializationOptions; }
183+
get { return _keyValuePairSerializationOptions; }
163184
set
164185
{
186+
if (value == null)
187+
{
188+
throw new ArgumentNullException("value");
189+
}
165190
EnsureNotFrozen();
166-
_valueSerializationOptions = value;
191+
_keyValuePairSerializationOptions = value;
167192
}
168193
}
169194

@@ -176,6 +201,7 @@ public IBsonSerializationOptions ValueSerializationOptions
176201
public override void ApplyAttribute(IBsonSerializer serializer, Attribute attribute)
177202
{
178203
EnsureNotFrozen();
204+
179205
var dictionaryOptionsAttribute = attribute as BsonDictionaryOptionsAttribute;
180206
if (dictionaryOptionsAttribute != null)
181207
{
@@ -198,14 +224,16 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
198224
}
199225
}
200226

227+
// any other attributes are applied to the values
201228
var valueType = typeof(object);
202229
if (serializer.GetType().IsGenericType)
203230
{
204-
valueType = serializer.GetType().GetGenericArguments()[1];
231+
valueType = serializer.GetType().GetGenericArguments()[1]; // TValue
205232
}
206233
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
207234

208-
if (_valueSerializationOptions == null)
235+
var valueSerializationOptions = _keyValuePairSerializationOptions.ValueSerializationOptions;
236+
if (valueSerializationOptions == null)
209237
{
210238
var valueDefaultSerializationOptions = valueSerializer.GetDefaultSerializationOptions();
211239

@@ -227,10 +255,14 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
227255
throw new NotSupportedException(message);
228256
}
229257

230-
_valueSerializationOptions = valueDefaultSerializationOptions.Clone();
258+
valueSerializationOptions = valueDefaultSerializationOptions.Clone();
231259
}
232260

233-
_valueSerializationOptions.ApplyAttribute(valueSerializer, attribute);
261+
valueSerializationOptions.ApplyAttribute(valueSerializer, attribute);
262+
_keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
263+
_keyValuePairSerializationOptions.Representation,
264+
_keyValuePairSerializationOptions.KeySerializationOptions,
265+
valueSerializationOptions);
234266
}
235267

236268
/// <summary>
@@ -239,7 +271,7 @@ public override void ApplyAttribute(IBsonSerializer serializer, Attribute attrib
239271
/// <returns>A cloned copy of the serialization options.</returns>
240272
public override IBsonSerializationOptions Clone()
241273
{
242-
return new DictionarySerializationOptions(_representation, _valueSerializationOptions);
274+
return new DictionarySerializationOptions(_representation, _keyValuePairSerializationOptions);
243275
}
244276

245277
/// <summary>
@@ -250,9 +282,9 @@ public override IBsonSerializationOptions Freeze()
250282
{
251283
if (!IsFrozen)
252284
{
253-
if (_valueSerializationOptions != null)
285+
if (_keyValuePairSerializationOptions != null)
254286
{
255-
_valueSerializationOptions.Freeze();
287+
_keyValuePairSerializationOptions.Freeze();
256288
}
257289
}
258290
return base.Freeze();

Bson/Serialization/Serializers/DictionaryGenericSerializer.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ public override object Deserialize(
6262
{
6363
var dictionarySerializationOptions = EnsureSerializationOptions(options);
6464
var dictionaryRepresentation = dictionarySerializationOptions.Representation;
65-
var keySerializationOptions = (IBsonSerializationOptions)null; // TODO: how should these be provided?
66-
var valueSerializationOptions = dictionarySerializationOptions.ValueSerializationOptions;
65+
var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions;
6766

6867
var bsonType = bsonReader.GetCurrentBsonType();
6968
if (bsonType == BsonType.Null)
@@ -92,7 +91,7 @@ public override object Deserialize(
9291
var key = (TKey)(object)bsonReader.ReadName();
9392
var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
9493
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
95-
var value = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, valueSerializationOptions);
94+
var value = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, keyValuePairSerializationOptions.ValueSerializationOptions);
9695
dictionary.Add(key, value);
9796
}
9897
bsonReader.ReadEndDocument();
@@ -102,10 +101,6 @@ public override object Deserialize(
102101
else if (bsonType == BsonType.Array)
103102
{
104103
var dictionary = CreateInstance(actualType);
105-
var keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
106-
(dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document,
107-
keySerializationOptions,
108-
valueSerializationOptions);
109104

110105
bsonReader.ReadStartArray();
111106
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
@@ -160,8 +155,7 @@ public override void Serialize(
160155
var dictionary = (IDictionary<TKey, TValue>)value;
161156
var dictionarySerializationOptions = EnsureSerializationOptions(options);
162157
var dictionaryRepresentation = dictionarySerializationOptions.Representation;
163-
var keySerializationOptions = (IBsonSerializationOptions)null; // TODO: how should these be provided?
164-
var valueSerializationOptions = dictionarySerializationOptions.ValueSerializationOptions;
158+
var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions;
165159

166160
if (dictionaryRepresentation == DictionaryRepresentation.Dynamic)
167161
{
@@ -191,17 +185,22 @@ public override void Serialize(
191185
foreach (var keyValuePair in dictionary)
192186
{
193187
bsonWriter.WriteName((string)(object)keyValuePair.Key);
194-
BsonSerializer.Serialize(bsonWriter, typeof(TValue), keyValuePair.Value, valueSerializationOptions);
188+
BsonSerializer.Serialize(bsonWriter, typeof(TValue), keyValuePair.Value, keyValuePairSerializationOptions.ValueSerializationOptions);
195189
}
196190
bsonWriter.WriteEndDocument();
197191
break;
198192

199193
case DictionaryRepresentation.ArrayOfArrays:
200194
case DictionaryRepresentation.ArrayOfDocuments:
201-
var keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
202-
(dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document,
203-
keySerializationOptions,
204-
valueSerializationOptions);
195+
// override KeyValuePair representation if necessary
196+
var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document;
197+
if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation)
198+
{
199+
keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
200+
keyValuePairRepresentation,
201+
keyValuePairSerializationOptions.KeySerializationOptions,
202+
keyValuePairSerializationOptions.ValueSerializationOptions);
203+
}
205204

206205
bsonWriter.WriteStartArray();
207206
foreach (var keyValuePair in dictionary)

Bson/Serialization/Serializers/DictionarySerializer.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ public override object Deserialize(
7474
{
7575
var dictionarySerializationOptions = EnsureSerializationOptions(options);
7676
var dictionaryRepresentation = dictionarySerializationOptions.Representation;
77-
var keySerializationOptions = (IBsonSerializationOptions)null; // TODO: how should these be provided?
78-
var valueSerializationOptions = dictionarySerializationOptions.ValueSerializationOptions;
77+
var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions;
7978

8079
var bsonType = bsonReader.GetCurrentBsonType();
8180
if (bsonType == BsonType.Null)
@@ -104,7 +103,7 @@ public override object Deserialize(
104103
var key = bsonReader.ReadName();
105104
var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(object));
106105
var valueSerializer = BsonSerializer.LookupSerializer(valueType);
107-
var value = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, valueSerializationOptions);
106+
var value = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, keyValuePairSerializationOptions.ValueSerializationOptions);
108107
dictionary.Add(key, value);
109108
}
110109
bsonReader.ReadEndDocument();
@@ -114,10 +113,6 @@ public override object Deserialize(
114113
else if (bsonType == BsonType.Array)
115114
{
116115
var dictionary = CreateInstance(actualType);
117-
var keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
118-
(dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document,
119-
keySerializationOptions,
120-
valueSerializationOptions);
121116

122117
bsonReader.ReadStartArray();
123118
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
@@ -172,8 +167,7 @@ public override void Serialize(
172167
var dictionary = (IDictionary)value;
173168
var dictionarySerializationOptions = EnsureSerializationOptions(options);
174169
var dictionaryRepresentation = dictionarySerializationOptions.Representation;
175-
var keySerializationOptions = (IBsonSerializationOptions)null; // TODO: how should these be provided?
176-
var valueSerializationOptions = dictionarySerializationOptions.ValueSerializationOptions;
170+
var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions;
177171

178172
if (dictionaryRepresentation == DictionaryRepresentation.Dynamic)
179173
{
@@ -196,16 +190,23 @@ public override void Serialize(
196190
foreach (DictionaryEntry dictionaryEntry in dictionary)
197191
{
198192
bsonWriter.WriteName((string)dictionaryEntry.Key);
199-
BsonSerializer.Serialize(bsonWriter, typeof(object), dictionaryEntry.Value, valueSerializationOptions);
193+
BsonSerializer.Serialize(bsonWriter, typeof(object), dictionaryEntry.Value, keyValuePairSerializationOptions.ValueSerializationOptions);
200194
}
201195
bsonWriter.WriteEndDocument();
202196
break;
197+
203198
case DictionaryRepresentation.ArrayOfArrays:
204199
case DictionaryRepresentation.ArrayOfDocuments:
205-
var keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
206-
(dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document,
207-
keySerializationOptions,
208-
valueSerializationOptions);
200+
// override KeyValuePair representation if necessary
201+
var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document;
202+
if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation)
203+
{
204+
keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(
205+
keyValuePairRepresentation,
206+
keyValuePairSerializationOptions.KeySerializationOptions,
207+
keyValuePairSerializationOptions.ValueSerializationOptions);
208+
}
209+
209210
bsonWriter.WriteStartArray();
210211
foreach (DictionaryEntry dictionaryEntry in dictionary)
211212
{

0 commit comments

Comments
 (0)