private static List<SettingsObject> BuildGraphImpl(object attributedObject, Stack<object> referenceStack)
{
List<SettingsObject> graph = new List<SettingsObject>();
// If arributed object is null return empty graph
if(attributedObject == null)
{
return graph;
}
// If a circular reference is detected then return empty graph
if(referenceStack.Contains(attributedObject))
{
return graph;
}
// Push the current attributed part onto the reference stack
referenceStack.Push(attributedObject);
// Loop through properties on the attributed object
foreach(var property in attributedObject.GetType().GetProperties())
{
// Try get value from property
object value = null;
try
{
value = property.GetValue(attributedObject, null);
}
// ReSharper disable EmptyGeneralCatchClause
catch(Exception)
// ReSharper restore EmptyGeneralCatchClause
{
#if DEBUG
//DIE execution DIE ... dude what are you doing?! Fix this otherwise the property won't show as an option in the settings treeview.
#else
// If there was a problem skip this property
continue;
#endif
}
// If value is null skip this property
if(value == null)
{
continue;
}
// If a circular reference is detected then skip this property
if(referenceStack.Contains(value))
{
continue;
}
// Check if the property is adorned with the SettingsObjectAtribute
object[] attributes = property.GetCustomAttributes(typeof(SettingsObjectAttribute), true);
if(attributes.Length > 0)
{
SettingsObjectAttribute settingsObjectAttribute = attributes[0] as SettingsObjectAttribute;
// Add settings object to graph
if(settingsObjectAttribute != null)
{
graph.Add(new SettingsObject(value, settingsObjectAttribute.View, settingsObjectAttribute.ViewModel));
}
}
}
// Find nested settings objects
foreach(SettingsObject item in graph)
{
item.Children.AddRange(BuildGraphImpl(item.Object, referenceStack));
}
// Pop from the reference stack
referenceStack.Pop();
return graph;
}