Even more powerful dictionary detection
There were some more cases where an IDictionary<string, T> was not being detected by the UpcastDictionary.
This commit is contained in:
parent
80824c4e4b
commit
55ff1ef5de
|
@ -202,5 +202,22 @@ namespace Mustache.Test
|
||||||
};
|
};
|
||||||
CollectionAssert.AreEqual(expected, values, "The enumerator did not return the correct pairs.");
|
CollectionAssert.AreEqual(expected, values, "The enumerator did not return the correct pairs.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Newtonsoft's JSON.NET has an object called JObject. This is a concrete class
|
||||||
|
/// that inherits from IDictionary<string, JToken>. The UpcastDictionary
|
||||||
|
/// should be able to handle this type.
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void ShouldHandleConcreteClassInheritingFromDictionary()
|
||||||
|
{
|
||||||
|
var dictionary = new ConcreteDictionary() { { "Name", "Bob" } };
|
||||||
|
var result = UpcastDictionary.Create(dictionary);
|
||||||
|
Assert.AreEqual(dictionary["Name"], result["Name"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConcreteDictionary : Dictionary<string, string>
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,6 @@ using System.Runtime.InteropServices;
|
||||||
[assembly: CLSCompliant(true)]
|
[assembly: CLSCompliant(true)]
|
||||||
[assembly: ComVisible(false)]
|
[assembly: ComVisible(false)]
|
||||||
[assembly: Guid("e5a4263d-d450-4d85-a4d5-44c0a2822668")]
|
[assembly: Guid("e5a4263d-d450-4d85-a4d5-44c0a2822668")]
|
||||||
[assembly: AssemblyVersion("0.2.5.0")]
|
[assembly: AssemblyVersion("0.2.6.0")]
|
||||||
[assembly: AssemblyFileVersion("0.2.5.0")]
|
[assembly: AssemblyFileVersion("0.2.6.0")]
|
||||||
[assembly: InternalsVisibleTo("mustache-sharp.test")]
|
[assembly: InternalsVisibleTo("mustache-sharp.test")]
|
|
@ -20,11 +20,48 @@ namespace Mustache
|
||||||
return sourceDictionary;
|
return sourceDictionary;
|
||||||
}
|
}
|
||||||
Type sourceType = source.GetType();
|
Type sourceType = source.GetType();
|
||||||
if (!sourceType.IsGenericType)
|
var types = getTypes(sourceType);
|
||||||
|
return getDictionary(types, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<Type> getTypes(Type type)
|
||||||
|
{
|
||||||
|
HashSet<Type> types = new HashSet<Type>();
|
||||||
|
getTypes(types, type);
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getTypes(HashSet<Type> types, Type type)
|
||||||
|
{
|
||||||
|
if (type == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
types.Add(type);
|
||||||
|
getTypes(types, type.BaseType);
|
||||||
|
foreach (Type interfaceType in type.GetInterfaces())
|
||||||
|
{
|
||||||
|
getTypes(types, interfaceType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IDictionary<string, object> getDictionary(IEnumerable<Type> types, object source)
|
||||||
|
{
|
||||||
|
var dictionaries = from type in types
|
||||||
|
let valueType = getValueType(type)
|
||||||
|
where valueType != null
|
||||||
|
let upcastType = typeof(UpcastDictionary<>).MakeGenericType(valueType)
|
||||||
|
select (IDictionary<string, object>)Activator.CreateInstance(upcastType, source);
|
||||||
|
return dictionaries.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type getValueType(Type type)
|
||||||
|
{
|
||||||
|
if (!type.IsGenericType)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Type[] argumentTypes = sourceType.GetGenericArguments();
|
Type[] argumentTypes = type.GetGenericArguments();
|
||||||
if (argumentTypes.Length != 2)
|
if (argumentTypes.Length != 2)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -36,12 +73,11 @@ namespace Mustache
|
||||||
}
|
}
|
||||||
Type valueType = argumentTypes[1];
|
Type valueType = argumentTypes[1];
|
||||||
Type genericType = typeof(IDictionary<,>).MakeGenericType(typeof(string), valueType);
|
Type genericType = typeof(IDictionary<,>).MakeGenericType(typeof(string), valueType);
|
||||||
if (!genericType.IsAssignableFrom(sourceType))
|
if (!genericType.IsAssignableFrom(type))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Type upcastType = typeof(UpcastDictionary<>).MakeGenericType(valueType);
|
return valueType;
|
||||||
return (IDictionary<string, object>)Activator.CreateInstance(upcastType, source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue