protected void InternalRecursiveBindObjectInstance(object instance, String prefix, CompositeNode node)
{
if (node == null || instance == null)
{
return;
}
BeforeBinding(instance, prefix, node);
if (PerformCustomBinding(instance, prefix, node))
{
return;
}
PushInstance(instance, prefix);
ErrorSummary summary = new ErrorSummary();
validationErrorSummaryPerInstance[instance] = summary;
Type instanceType = instance.GetType();
PropertyInfo[] props = instanceType.GetProperties(PropertiesBindingFlags);
string nodeFullName = node.FullName;
foreach(PropertyInfo prop in props)
{
if (ShouldIgnoreProperty(prop, nodeFullName))
{
continue;
}
Type propType = prop.PropertyType;
String paramName = prop.Name;
String translatedParamName = Translate(instanceType, paramName);
if (translatedParamName == null)
{
continue;
}
bool isSimpleProperty = IsSimpleProperty(propType);
// There are some caveats by running the validators here.
// We should follow the validator's execution order...
if (isSimpleProperty)
{
if (CheckForValidationFailures(instance, instanceType, prop, node, translatedParamName, prefix, summary))
{
continue;
}
}
BeforeBindingProperty(instance, prop, prefix, node);
try
{
bool conversionSucceeded;
if (isSimpleProperty)
{
object value = ConvertToSimpleValue(propType, translatedParamName, node, out conversionSucceeded);
if (conversionSucceeded)
{
SetPropertyValue(instance, prop, value);
}
}
else
{
// if the property is an object, we look if it is already instanciated
object value = prop.GetValue(instance, null);
Node nestedNode = node.GetChildNode(paramName);
if (nestedNode != null)
{
if (ShouldRecreateInstance(value, propType, paramName, nestedNode))
{
value = InternalBindObject(propType, paramName, nestedNode, out conversionSucceeded);
if (conversionSucceeded)
{
SetPropertyValue(instance, prop, value);
}
}
else
{
InternalRecursiveBindObjectInstance(value, paramName, nestedNode);
}
}
CheckForValidationFailures(instance, instanceType, prop, value, translatedParamName, prefix, summary);
}
}
catch(Exception ex)
{
errors.Add(new DataBindError(prefix, prop.Name, ex));
}
}
PopInstance(instance, prefix);
AfterBinding(instance, prefix, node);
}