/// <summary> /// Uses reflection to recursively generate UIDisplayData object /// If UIAttribute.DisplayName == "", the UIField DisplayName will be generated by splitting the property name at capital letters (assuming we use camel case) /// A property/field marked with the attribute [UIProperty] will be added UIDisplayData.UIFields /// A property/field marked with the attribute [UICollection] will be recursively processed and added to UIDisplayData.NestedUIDisplayData /// </summary> /// <param name="obj"></param> /// <returns></returns> static public UIDisplayData GetUIData(IHasUIData obj) { var displayData = new UIDisplayData { DisplayName = obj.UIDisplayName }; PopulateUIData(obj, ref displayData); return(displayData); }
/// <summary> /// Get UI data from complex (class) members marked with UICollection /// </summary> /// <param name="obj"></param> /// <param name="UIData"></param> static void GetUICollections(IHasUIData obj, ref UIDisplayData UIData) { foreach (var prop in GetUICollectionProperties(obj)) { var uiattribute = prop.GetCustomAttribute(typeof(UICollection)) as UICollection; var propertyName = prop.Name; var displayName = uiattribute.DisplayName == "" ? prop.Name.SplitCamelCase() : uiattribute.DisplayName; var nestedData = new UIDisplayData() { DisplayName = displayName }; if (prop.PropertyType.GetInterface(typeof(IHasUIData).Name) != null) { nestedData.ObjectType = prop.PropertyType.Name; PopulateUIData((IHasUIData)prop.GetValue(obj), ref nestedData); UIData.NestedUIDisplayData.Add(propertyName, nestedData); } else if (prop.PropertyType.GetInterface(typeof(IEnumerable).Name) != null) { nestedData.ObjectType = GetFullType(prop.PropertyType); PopulateUIData((IEnumerable)prop.GetValue(obj), ref nestedData); UIData.NestedUIDisplayData.Add(propertyName, nestedData); } } foreach (var field in GetUICollectionFields(obj)) { var uiattribute = field.GetCustomAttribute(typeof(UICollection)) as UICollection; var fieldName = field.Name; var displayName = uiattribute.DisplayName == "" ? field.Name.SplitCamelCase() : uiattribute.DisplayName; var nestedData = new UIDisplayData() { DisplayName = displayName }; if (field.FieldType.GetInterface(typeof(IHasUIData).Name) != null) { nestedData.ObjectType = field.FieldType.Name; PopulateUIData((IHasUIData)field.GetValue(obj), ref nestedData); UIData.NestedUIDisplayData.Add(fieldName, nestedData); } else if (field.FieldType.GetInterface(typeof(IEnumerable).Name) != null) { nestedData.ObjectType = GetFullType(field.FieldType); PopulateUIData((IEnumerable)field.GetValue(obj), ref nestedData); UIData.NestedUIDisplayData.Add(fieldName, nestedData); } } }
/// <summary> /// Get UI data for IEnumerable<IHasUIData> and Dictionary<t, IHasUIData> /// </summary> /// <param name="obj"></param> /// <param name="UIData"></param> static void PopulateUIData(IEnumerable obj, ref UIDisplayData UIData) { var genericArgs = obj.GetType().GetGenericArguments(); var t = obj.GetType(); if (genericArgs[0].GetInterface(typeof(IHasUIData).Name) != null) { int i = 0; foreach (var v in obj) { var nestedData = new UIDisplayData(); nestedData.DisplayName = ((IHasUIData)v).UIDisplayName; PopulateUIData((IHasUIData)v, ref nestedData); UIData.NestedUIDisplayData.Add(i.ToString(), nestedData); i++; } } else if (genericArgs[0].GetInterface(typeof(IEnumerable).Name) != null) { //IEnumerable<IEnumerable>, don't know what to do about the display name... int i = 0; foreach (var v in obj) { var nestedData = new UIDisplayData(); nestedData.DisplayName = ((IHasUIData)v.GetType().GetProperty("Key").GetValue(v)).UIDisplayName; UIData.NestedUIDisplayData.Add(i.ToString(), nestedData); i++; } } else if (genericArgs.Length == 2 && genericArgs[1].GetInterface(typeof(IHasUIData).Name) != null) { //Dictionaries have 2 generic arguments //if Value implements IHasUIData: foreach (var v in obj) { var nestedData = new UIDisplayData(); nestedData.DisplayName = ((IHasUIData)v.GetType().GetProperty("Value").GetValue(v)).UIDisplayName; PopulateUIData((IHasUIData)(v.GetType().GetProperty("Value").GetValue(v)), ref nestedData); UIData.NestedUIDisplayData.Add(v.GetType().GetProperty("Key").GetValue(v).ToString(), nestedData); } } }
/// <summary> /// Get UI data from simple (non-class) members marked with UIProperty /// </summary> /// <param name="obj"></param> /// <param name="UIData"></param> static void GetUIFields(IHasUIData obj, ref UIDisplayData UIData) { foreach (var prop in GetUIPropertyProperties(obj)) { var uiattribute = prop.GetCustomAttribute(typeof(UIProperty)) as UIProperty; var propertyName = prop.Name; var displayName = uiattribute.DisplayName == "" ? prop.Name.SplitCamelCase() : uiattribute.DisplayName; var displayValue = prop.GetValue(obj).ToString(); var displayOrder = uiattribute.DisplayOrder; var units = uiattribute.Units; var isDisplayed = uiattribute.IsDisplayed; var type = prop.PropertyType.Name; UIData.UIFields.Add(propertyName, new UIField { DisplayName = displayName, DisplayValue = displayValue, DisplayOrder = displayOrder, Units = units, IsDisplayed = isDisplayed, Type = type }); } foreach (var field in GetUIPropertyFields(obj)) { var uiattribute = field.GetCustomAttribute(typeof(UIProperty)) as UIProperty; var propertyName = field.Name; var displayName = uiattribute.DisplayName == "" ? field.Name.SplitCamelCase() : uiattribute.DisplayName; var displayValue = field.GetValue(obj).ToString(); var displayOrder = uiattribute.DisplayOrder; var units = uiattribute.Units; var isDisplayed = uiattribute.IsDisplayed; var type = field.FieldType.Name; UIData.UIFields.Add(propertyName, new UIField { DisplayName = displayName, DisplayValue = displayValue, DisplayOrder = displayOrder, Units = units, IsDisplayed = isDisplayed, Type = type }); } }
/// <summary> /// If displayName == null, DisplayName is set to obj.UIDisplayName /// </summary> /// <param name="obj"></param> /// <param name="UIData"></param> /// <param name="displayName"></param> static void PopulateUIData(IHasUIData obj, ref UIDisplayData UIData) { UIData.ObjectType = obj.GetType().Name; GetUIFields(obj, ref UIData); GetUICollections(obj, ref UIData); }