diff --git a/Bson/Bson.csproj b/Bson/Bson.csproj
index c5b607aea3..81a124810b 100644
--- a/Bson/Bson.csproj
+++ b/Bson/Bson.csproj
@@ -87,8 +87,9 @@
-
+
+
diff --git a/Bson/DefaultSerializer/Serializers/CollectionSerializersGeneric.cs b/Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs
similarity index 99%
rename from Bson/DefaultSerializer/Serializers/CollectionSerializersGeneric.cs
rename to Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs
index 37a5dc6b58..2ab9d77d2d 100644
--- a/Bson/DefaultSerializer/Serializers/CollectionSerializersGeneric.cs
+++ b/Bson/DefaultSerializer/Serializers/CollectionGenericSerializers.cs
@@ -39,6 +39,9 @@ namespace MongoDB.Bson.DefaultSerializer {
public class EnumerableSerializer : BsonBaseSerializer {
#region constructors
+ public EnumerableSerializer() {
+ }
+
public EnumerableSerializer(
object serializationOptions
) {
diff --git a/Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs b/Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs
new file mode 100644
index 0000000000..9da36317cc
--- /dev/null
+++ b/Bson/DefaultSerializer/Serializers/DictionaryGenericSerializer.cs
@@ -0,0 +1,158 @@
+/* Copyright 2010 10gen Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+using MongoDB.Bson.IO;
+using MongoDB.Bson.Serialization;
+
+namespace MongoDB.Bson.DefaultSerializer {
+ public static class DictionarySerializerRegistration {
+ #region public static methods
+ public static void RegisterGenericSerializerDefinitions() {
+ BsonSerializer.RegisterGenericSerializerDefinition(typeof(Dictionary<,>), typeof(DictionarySerializer<,>));
+ BsonSerializer.RegisterGenericSerializerDefinition(typeof(IDictionary<,>), typeof(DictionarySerializer<,>));
+ BsonSerializer.RegisterGenericSerializerDefinition(typeof(SortedDictionary<,>), typeof(DictionarySerializer<,>));
+ BsonSerializer.RegisterGenericSerializerDefinition(typeof(SortedList<,>), typeof(DictionarySerializer<,>));
+ }
+ #endregion
+ }
+
+ public class DictionarySerializer : BsonBaseSerializer {
+ #region constructors
+ public DictionarySerializer() {
+ }
+
+ public DictionarySerializer(
+ object serializationOptions
+ ) {
+ }
+ #endregion
+
+ #region public methods
+ public override object Deserialize(
+ BsonReader bsonReader,
+ Type nominalType
+ ) {
+ var bsonType = bsonReader.CurrentBsonType;
+ if (bsonType == BsonType.Null) {
+ bsonReader.ReadNull();
+ return null;
+ } else if (bsonType == BsonType.Document) {
+ var dictionary = CreateInstance(nominalType);
+ bsonReader.ReadStartDocument();
+ var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
+ while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
+ var key = (TKey) (object) bsonReader.ReadName();
+ var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
+ var valueSerializer = BsonSerializer.LookupSerializer(valueType);
+ var value = (TValue) valueSerializer.Deserialize(bsonReader, typeof(TValue));
+ dictionary.Add(key, value);
+ }
+ bsonReader.ReadEndDocument();
+ return dictionary;
+ } else if (bsonType == BsonType.Array) {
+ var dictionary = CreateInstance(nominalType);
+ bsonReader.ReadStartArray();
+ var keyDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TKey));
+ var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
+ while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
+ bsonReader.SkipName();
+ bsonReader.ReadStartArray();
+ bsonReader.ReadBsonType();
+ bsonReader.SkipName();
+ var keyType = keyDiscriminatorConvention.GetActualType(bsonReader, typeof(TKey));
+ var keySerializer = BsonSerializer.LookupSerializer(keyType);
+ var key = (TKey) keySerializer.Deserialize(bsonReader, typeof(TKey));
+ bsonReader.ReadBsonType();
+ bsonReader.SkipName();
+ var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
+ var valueSerializer = BsonSerializer.LookupSerializer(valueType);
+ var value = (TValue) valueSerializer.Deserialize(bsonReader, typeof(TValue));
+ bsonReader.ReadEndArray();
+ dictionary.Add(key, value);
+ }
+ bsonReader.ReadEndArray();
+ return dictionary;
+ } else {
+ var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
+ throw new FileFormatException(message);
+ }
+ }
+
+ public override void Serialize(
+ BsonWriter bsonWriter,
+ Type nominalType,
+ object value,
+ bool serializeIdFirst
+ ) {
+ if (value == null) {
+ bsonWriter.WriteNull();
+ } else {
+ var dictionary = (IDictionary) value;
+ if (
+ typeof(TKey) == typeof(string) ||
+ (typeof(TKey) == typeof(object) && dictionary.Keys.All(o => o.GetType() == typeof(string)))
+ ) {
+ bsonWriter.WriteStartDocument();
+ int index = 0;
+ foreach (KeyValuePair entry in dictionary) {
+ bsonWriter.WriteName((string) (object) entry.Key);
+ BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value);
+ index++;
+ }
+ bsonWriter.WriteEndDocument();
+ } else {
+ bsonWriter.WriteStartArray();
+ int index = 0;
+ foreach (KeyValuePair entry in dictionary) {
+ bsonWriter.WriteStartArray(index.ToString());
+ bsonWriter.WriteName("0");
+ BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Key);
+ bsonWriter.WriteName("1");
+ BsonSerializer.Serialize(bsonWriter, typeof(object), entry.Value);
+ bsonWriter.WriteEndArray();
+ index++;
+ }
+ bsonWriter.WriteEndArray();
+ }
+ }
+ }
+ #endregion
+
+ #region private methods
+ private IDictionary CreateInstance(
+ Type nominalType
+ ) {
+ if (nominalType == typeof(Dictionary)) {
+ return new Dictionary();
+ } else if (nominalType == typeof(IDictionary)) {
+ return new Dictionary();
+ } else if (nominalType == typeof(SortedDictionary)) {
+ return new SortedDictionary();
+ } else if (nominalType == typeof(SortedList)) {
+ return new SortedList();
+ } else {
+ var message = string.Format("Invalid nominalType for DictionarySerializer<{0}, {1}>: {2}", typeof(TKey).FullName, typeof(TValue).FullName, nominalType.FullName);
+ throw new BsonSerializationException(message);
+ }
+ }
+ #endregion
+ }
+}
diff --git a/Bson/DefaultSerializer/Serializers/DictionarySerializer.cs b/Bson/DefaultSerializer/Serializers/DictionarySerializer.cs
index 8da84bfdcf..a2c26b04f2 100644
--- a/Bson/DefaultSerializer/Serializers/DictionarySerializer.cs
+++ b/Bson/DefaultSerializer/Serializers/DictionarySerializer.cs
@@ -59,6 +59,19 @@ namespace MongoDB.Bson.DefaultSerializer {
if (bsonType == BsonType.Null) {
bsonReader.ReadNull();
return null;
+ } else if (bsonType == BsonType.Document) {
+ var dictionary = CreateInstance(nominalType);
+ bsonReader.ReadStartDocument();
+ var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
+ while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
+ var key = bsonReader.ReadName();
+ var valueType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
+ var valueSerializer = BsonSerializer.LookupSerializer(valueType);
+ var value = valueSerializer.Deserialize(bsonReader, typeof(object));
+ dictionary.Add(key, value);
+ }
+ bsonReader.ReadEndDocument();
+ return dictionary;
} else if (bsonType == BsonType.Array) {
var dictionary = CreateInstance(nominalType);
bsonReader.ReadStartArray();
@@ -81,19 +94,6 @@ namespace MongoDB.Bson.DefaultSerializer {
}
bsonReader.ReadEndArray();
return dictionary;
- } else if (bsonType == BsonType.Document) {
- var dictionary = CreateInstance(nominalType);
- bsonReader.ReadStartDocument();
- var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
- while (bsonReader.ReadBsonType() != BsonType.EndOfDocument) {
- var key = bsonReader.ReadName();
- var valueType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
- var valueSerializer = BsonSerializer.LookupSerializer(valueType);
- var value = valueSerializer.Deserialize(bsonReader, typeof(object));
- dictionary.Add(key, value);
- }
- bsonReader.ReadEndDocument();
- return dictionary;
} else {
var message = string.Format("Can't deserialize a {0} from BsonType {1}", nominalType.FullName, bsonType);
throw new FileFormatException(message);
@@ -110,7 +110,16 @@ namespace MongoDB.Bson.DefaultSerializer {
bsonWriter.WriteNull();
} else {
var dictionary = (IDictionary) value;
- if (dictionary.Keys.Cast