Skip to content

Commit

Permalink
Merge pull request #1 from radiy/master
Browse files Browse the repository at this point in the history
fix generic list instance binding
  • Loading branch information
hammett committed Aug 26, 2011
2 parents 4738822 + 64a62e1 commit ac630b1
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 33 deletions.
Expand Up @@ -46,7 +46,6 @@ public void CanBindToGenericListInstance()
int expectedValue = 12;

var myList = new List<int>();
myList.Add(expectedValue);

var binder = new DataBinder();
CompositeNode paramsNode = GetParamsNode(expectedValue);
Expand Down
71 changes: 39 additions & 32 deletions src/Castle.Components.Binder/DataBinder.cs
Expand Up @@ -195,7 +195,18 @@ public void BindObjectInstance(object instance, string prefix, CompositeNode tre
prefixStack = new Stack<string>();

excludedPropertyList = CreateNormalizedList(excludedProperties);
allowedPropertyList = CreateNormalizedList(allowedProperties);
allowedPropertyList = CreateNormalizedList(allowedProperties);

if (instance != null)
{
var instanceType = instance.GetType();
if (IsGenericList(instanceType))
{
bool success;
var elemType = instanceType.GetGenericArguments()[0];
ConvertToGenericList((IList)instance, elemType, prefix, treeRoot.GetChildNode(prefix), out success);
}
}

InternalRecursiveBindObjectInstance(instance, prefix, treeRoot.GetChildNode(prefix));
}
Expand Down Expand Up @@ -265,7 +276,7 @@ protected object InternalBindObject(Type instanceType, String paramPrefix, Node
}
if (IsGenericList(instanceType))
{
return InternalBindGenericList(instanceType, paramPrefix, node, out succeeded);
return ConvertToGenericList(instanceType, paramPrefix, node, out succeeded);
}
succeeded = true;
object instance = CreateInstance(instanceType, paramPrefix, node);
Expand Down Expand Up @@ -540,20 +551,8 @@ internal static bool IsGenericList(Type instanceType)
}
Type listType = typeof (IList<>).MakeGenericType(genericArgs[0]);
return listType.IsAssignableFrom(instanceType);
}

private object InternalBindGenericList(Type instanceType, string paramPrefix, Node node, out bool succeeded)
{
succeeded = false;

if (node == null)
{
return CreateInstance(instanceType, paramPrefix, node);
}

return ConvertToGenericList(instanceType, paramPrefix, node, out succeeded);
}

}

#endregion

#region CreateInstance
Expand Down Expand Up @@ -791,27 +790,42 @@ private ArrayList ConvertFlatNodesToList(Type elemType, Node[] nodes, out bool c
return validItems;
}

private object ConvertToGenericList(Type desiredType, String key, Node node, out bool conversionSucceeded)
{
private object ConvertToGenericList(Type desiredType, String key, Node node, out bool conversionSucceeded)
{
Type[] genericArgs = desiredType.GetGenericArguments();

if (genericArgs.Length == 0)
{
throw new BindingException("Can't infer the Generics placeholders (type parameters). Key {0}.", key);
}

Type elemType = genericArgs[0];
Type elemType = genericArgs[0];

Type desiredImplType = desiredType.IsInterface
? typeof (List<>).MakeGenericType(elemType)
: desiredType;
var target = (IList) CreateInstance(desiredImplType, key, node);
ConvertToGenericList(target, elemType, key, node, out conversionSucceeded);
return target;
}

private void ConvertToGenericList(IList target, Type elemType, String key, Node node, out bool conversionSucceeded)
{
conversionSucceeded = false;
if (node == null)
{
conversionSucceeded = false;
return CreateInstance(desiredType, key, node);
}
return;
else if (node.NodeType == NodeType.Leaf)
{
var leafNode = node as LeafNode;

return Converter.Convert(desiredType, leafNode.ValueType, leafNode.Value, out conversionSucceeded);
var values = leafNode.Value as Array;
if (values == null)
return;
for(var i = 0; i < values.Length; i++)
{
var result = Converter.Convert(elemType, leafNode.ValueType, values.GetValue(i), out conversionSucceeded);
if (result != null)
target.Add(result);
}
}
else if (node.NodeType == NodeType.Indexed)
{
Expand All @@ -828,18 +842,11 @@ private object ConvertToGenericList(Type desiredType, String key, Node node, out
convertedNodes = ConvertComplexNodesToList(elemType, indexedNode, out conversionSucceeded);
}

Type desiredImplType = desiredType.IsInterface
? typeof (List<>).MakeGenericType(elemType)
: desiredType;
var target = (IList) CreateInstance(desiredImplType, key, node);

foreach (object elem in convertedNodes)
{
if (elem != null)
target.Add(elem);
}

return target;
}
else
{
Expand Down

0 comments on commit ac630b1

Please sign in to comment.