Permalink
Browse files

added support for deserialization of dictionaries with complex types.

  • Loading branch information...
craiggwilson committed May 16, 2010
1 parent b33bccb commit 5004bf4790d749ea714c076b96cb661e7a306f16
@@ -131,11 +131,9 @@ public void CanSerializeGenericDictionary()
}
[Test]
- public void CanSerializeAndDeserializeGenericDictionarys()
+ public void CanDeserializeGenericDictionary()
{
- var expectedBson = Serialize<Document>(new Document("Property", new Document() { { "key1", 10 }, { "key2", 20 } }));
- var obj = new GenericDictionary{Property = new Dictionary<string, int> { { "key1", 10 }, { "key2", 20 } }};
- var bson = Serialize<GenericDictionary>(obj);
+ var bson = Serialize<Document>(new Document("Property", new Document() { { "key1", 10 }, { "key2", 20 } }));
var prop = Deserialize<GenericDictionary>(bson);
Assert.IsNotNull(prop);
@@ -145,6 +143,38 @@ public void CanSerializeAndDeserializeGenericDictionarys()
Assert.Contains(new KeyValuePair<string, int>("key2", 20), prop.Property);
}
+ public class GenericDictionaryWithComplexType
+ {
+ public Dictionary<string, GenericDictionaryComplexType> Property { get; set; }
+ }
+
+ public class GenericDictionaryComplexType
+ {
+ public string Name { get; set; }
+ }
+
+ [Test]
+ public void CanSerializeGenericDictionaryWithComplexType()
+ {
+ var expectedBson = Serialize<Document>(new Document("Property", new Document() { { "key1", new Document("Name", "a") }, { "key2", new Document("Name", "b") } }));
+ var obj = new GenericDictionaryWithComplexType { Property = new Dictionary<string, GenericDictionaryComplexType> { { "key1", new GenericDictionaryComplexType() { Name = "a" } }, { "key2", new GenericDictionaryComplexType() { Name = "b" } } } };
+ var bson = Serialize<GenericDictionaryWithComplexType>(obj);
+ Assert.AreEqual(expectedBson, bson);
+ }
+
+ [Test]
+ public void CanDeserializeGenericDictionaryWithComplexType()
+ {
+ var bson = Serialize<Document>(new Document("Property", new Document() { { "key1", new Document("Name", "a") }, { "key2", new Document("Name", "b") } }));
+ var prop = Deserialize<GenericDictionaryWithComplexType>(bson);
+
+ Assert.IsNotNull(prop);
+ Assert.IsNotNull(prop.Property);
+ Assert.AreEqual(2, prop.Property.Count);
+ Assert.IsTrue(prop.Property["key1"].Name == "a");
+ Assert.IsTrue(prop.Property["key2"].Name == "b");
+ }
+
public class HashSetHelper
{
public HashSet<string> Property { get; set; }
@@ -141,6 +141,8 @@
<Compile Include="MapReduce.cs" />
<Compile Include="Commands\MapReduceCommand.cs" />
<Compile Include="Results\MapReduceResult.cs" />
+ <Compile Include="Serialization\Builders\DictionaryBuilder.cs" />
+ <Compile Include="Serialization\Builders\PropertyDescriptor.cs" />
<Compile Include="Serialization\Descriptors\DictionaryPropertyDescriptor.cs" />
<Compile Include="Util\ScopedDictionary.cs" />
<Compile Include="Linq\Translators\AggregateChecker.cs" />
@@ -9,6 +9,7 @@ namespace MongoDB.Serialization
{
internal class BsonClassMapBuilder : IBsonObjectBuilder
{
+ private bool _isDictionary;
private readonly Stack<Type> _types;
private readonly IMappingStore _mappingStore;
@@ -21,6 +22,12 @@ public BsonClassMapBuilder(IMappingStore mappingStore, Type classType)
public object BeginObject()
{
+ if (_isDictionary)
+ {
+ _isDictionary = false;
+ return new DictionaryBuilder(_types.Peek());
+ }
+
if (_types.Peek() == null || _types.Peek() == typeof(Document))
return new DocumentBuilder();
@@ -51,7 +58,14 @@ public object EndArray(object instance)
public void BeginProperty(object instance, string name)
{
- _types.Push(((IObjectBuilder)instance).GetPropertyType(name));
+ var propDescriptor = ((IObjectBuilder)instance).GetPropertyDescriptor(name);
+ if (propDescriptor == null)
+ _types.Push(null);
+ else
+ {
+ _types.Push(propDescriptor.Type);
+ _isDictionary = propDescriptor.IsDictionary;
+ }
}
public void EndProperty(object instance, string name, object value)
@@ -57,9 +57,9 @@ private object GetTypedList()
/// </summary>
/// <param name="name">The name.</param>
/// <returns></returns>
- public Type GetPropertyType(string name)
+ public PropertyDescriptor GetPropertyDescriptor(string name)
{
- return _elementType;
+ return new PropertyDescriptor() { Type = _elementType };
}
/// <summary>
@@ -40,18 +40,23 @@ public object BuildObject()
return _instance;
}
- public Type GetPropertyType(string name)
+ public PropertyDescriptor GetPropertyDescriptor(string name)
{
var memberMap = _classMap.GetMemberMapFromAlias(name);
if (memberMap == null)
return null;
+ var type = memberMap.MemberReturnType;
+ bool isDictionary = false;
if (memberMap is CollectionMemberMap)
- return ((CollectionMemberMap)memberMap).ElementType;
+ type = ((CollectionMemberMap)memberMap).ElementType;
else if (memberMap is DictionaryMemberMap)
- return ((DictionaryMemberMap)memberMap).ValueType;
+ {
+ type = ((DictionaryMemberMap)memberMap).ValueType;
+ isDictionary = true;
+ }
- return memberMap.MemberReturnType;
+ return new PropertyDescriptor() { Type = type, IsDictionary = isDictionary };
}
}
}
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MongoDB.Serialization.Builders
+{
+ public class DictionaryBuilder : IObjectBuilder
+ {
+ private Document _document;
+ private Type _valueType;
+
+ public DictionaryBuilder(Type valueType)
+ {
+ _document = new Document();
+ _valueType = valueType;
+ }
+
+ public void AddProperty(string name, object value)
+ {
+ _document.Add(name, value);
+ }
+
+ public object BuildObject()
+ {
+ return _document;
+ }
+
+ public PropertyDescriptor GetPropertyDescriptor(string name)
+ {
+ return new PropertyDescriptor() { Type = _valueType, IsDictionary = false };
+ }
+ }
+}
@@ -38,9 +38,9 @@ public object BuildObject()
/// </summary>
/// <param name="name">The name.</param>
/// <returns></returns>
- public Type GetPropertyType(string name)
+ public PropertyDescriptor GetPropertyDescriptor(string name)
{
- return null;
+ return new PropertyDescriptor();
}
}
}
@@ -8,6 +8,6 @@ internal interface IObjectBuilder
object BuildObject();
- Type GetPropertyType(string name);
+ PropertyDescriptor GetPropertyDescriptor(string name);
}
}
@@ -43,16 +43,23 @@ public object BuildObject()
return _concreteEntityBuilder.BuildObject();
}
- public Type GetPropertyType(string name)
+ public PropertyDescriptor GetPropertyDescriptor(string name)
{
var memberMap = _classMap.GetMemberMapFromAlias(name);
if (memberMap == null)
return null;
+ var type = memberMap.MemberReturnType;
+ bool isDictionary = false;
if (memberMap is CollectionMemberMap)
- return ((CollectionMemberMap)memberMap).ElementType;
+ type = ((CollectionMemberMap)memberMap).ElementType;
+ else if (memberMap is DictionaryMemberMap)
+ {
+ type = ((DictionaryMemberMap)memberMap).ValueType;
+ isDictionary = true;
+ }
- return memberMap.MemberReturnType;
+ return new PropertyDescriptor() { Type = type, IsDictionary = isDictionary };
}
}
}
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MongoDB.Serialization.Builders
+{
+ public class PropertyDescriptor
+ {
+ public Type Type { get; set; }
+
+ public bool IsDictionary { get; set; }
+ }
+}
@@ -48,7 +48,7 @@ public override IEnumerable<BsonProperty> GetProperties()
/// <returns></returns>
private BsonPropertyValue GetValue(PropertyInfo propertyInfo)
{
- Type type;
+ Type type = null;
var value = propertyInfo.GetValue(_example, null);
if (value != null && typeof(Code).IsAssignableFrom(value.GetType()))
{
@@ -61,14 +61,16 @@ private BsonPropertyValue GetValue(PropertyInfo propertyInfo)
var memberMap = GetMemberMapFromMemberName(propertyInfo.Name);
if (memberMap != null)
{
- type = memberMap.MemberReturnType;
if (memberMap is CollectionMemberMap)
type = ((CollectionMemberMap)memberMap).ElementType;
else if (memberMap is DictionaryMemberMap)
{
type = ((DictionaryMemberMap)memberMap).ValueType;
isDictionary = true;
}
+
+ if (type == null || type == typeof(object))
+ type = memberMap.MemberReturnType;
}
else
type = propertyInfo.PropertyType;
No changes.

0 comments on commit 5004bf4

Please sign in to comment.