/// <summary> /// Initializes all fields in the given region. /// </summary> /// <param name="scope">The current service scope</param> /// <param name="region">The region</param> /// <param name="regionType">The region type</param> /// <param name="managerInit">If this is initialization used by the manager</param> private async Task InitRegionAsync(IServiceScope scope, object region, ContentTypeRegion regionType, bool managerInit) { if (region != null) { if (regionType.Fields.Count == 1) { // This region only has one field, that means // the region is in fact a field. await InitFieldAsync(scope, region, managerInit).ConfigureAwait(false); } else { var type = region.GetType(); // Initialize all fields foreach (var fieldType in regionType.Fields) { var field = type.GetPropertyValue(fieldType.Id, region); if (field != null) { await InitFieldAsync(scope, field, managerInit).ConfigureAwait(false); } } } } }
/// <summary> /// Creates a new dynamic region. /// </summary> /// <param name="scope">The current service scope</param> /// <param name="regionType">The region type</param> /// <param name="initFields">If fields should be initialized</param> /// <param name="managerInit">If manager init should be performed on the fields</param> /// <returns>The created region</returns> private async Task <object> CreateDynamicRegionAsync(IServiceScope scope, ContentTypeRegion regionType, bool initFields = true, bool managerInit = false) { if (regionType.Fields.Count == 1) { var field = CreateField(regionType.Fields[0]); if (field != null) { if (initFields) { await InitFieldAsync(scope, field, managerInit).ConfigureAwait(false); } return(field); } } else { var reg = new ExpandoObject(); foreach (var fieldType in regionType.Fields) { var field = CreateField(fieldType); if (field != null) { if (initFields) { await InitFieldAsync(scope, field, managerInit).ConfigureAwait(false); } ((IDictionary <string, object>)reg).Add(fieldType.Id, field); } } return(reg); } return(null); }
private Tuple <int?, ContentTypeRegion> GetRegionType(PropertyInfo prop) { var attr = prop.GetCustomAttribute <RegionAttribute>(); if (attr != null) { var isCollection = typeof(IEnumerable).IsAssignableFrom(prop.PropertyType); var regionType = new ContentTypeRegion { Id = prop.Name, Title = attr.Title, Description = attr.Description, Collection = isCollection, ListTitleField = attr.ListTitle, ListTitlePlaceholder = attr.ListPlaceholder, ListExpand = attr.ListExpand, Icon = attr.Icon, Display = attr.Display, Width = attr.Width }; int?sortOrder = attr.SortOrder != Int32.MaxValue ? attr.SortOrder : (int?)null; Type type = null; if (!isCollection) { type = prop.PropertyType; } else { type = prop.PropertyType.GenericTypeArguments.First(); } if (typeof(IField).IsAssignableFrom(type)) { var appFieldType = App.Fields.GetByType(type); if (appFieldType == null) { RegisterField(type); appFieldType = App.Fields.GetByType(type); // This is a single field region, but the type is missing. // Discard the entire region if (appFieldType == null) { return(null); } } regionType.Fields.Add(new ContentTypeField { Id = "Default", Type = appFieldType.TypeName }); } else { var sortedFields = new List <Tuple <int?, ContentTypeField> >(); foreach (var fieldProp in type.GetProperties(App.PropertyBindings)) { var fieldType = GetFieldType(fieldProp); if (fieldType != null) { sortedFields.Add(fieldType); } } // First add sorted fields foreach (var fieldType in sortedFields.Where(t => t.Item1.HasValue)) { regionType.Fields.Add(fieldType.Item2); } // Then add the unsorted fields foreach (var fieldType in sortedFields.Where(t => !t.Item1.HasValue)) { regionType.Fields.Add(fieldType.Item2); } // Skip regions without fields. if (regionType.Fields.Count == 0) { return(null); } } return(new Tuple <int?, ContentTypeRegion>(sortOrder, regionType)); } return(null); }
/// <summary> /// Creates a new region. /// </summary> /// <param name="scope">The current service scope</param> /// <param name="model">The model to create the region for</param> /// <param name="modelType">The model type</param> /// <param name="regionType">The region type</param> /// <param name="initFields">If fields should be initialized</param> /// <returns>The created region</returns> private async Task <object> CreateRegionAsync(IServiceScope scope, object model, Type modelType, ContentTypeRegion regionType, bool initFields = true) { if (regionType.Fields.Count == 1) { var field = CreateField(regionType.Fields[0]); if (field != null) { if (initFields) { await InitFieldAsync(scope, field, false).ConfigureAwait(false); } return(field); } } else { var property = modelType.GetProperty(regionType.Id, App.PropertyBindings); if (property != null) { var reg = Activator.CreateInstance(property.PropertyType); foreach (var fieldType in regionType.Fields) { var field = CreateField(fieldType); if (field != null) { if (initFields) { await InitFieldAsync(scope, field, false).ConfigureAwait(false); } reg.GetType().SetPropertyValue(fieldType.Id, reg, field); } } return(reg); } } return(null); }
/// <summary> /// Initializes all fields in the given dynamic region. /// </summary> /// <param name="scope">The current service scope</param> /// <param name="region">The region</param> /// <param name="regionType">The region type</param> /// <param name="managerInit">If this is initialization used by the manager</param> private async Task InitDynamicRegionAsync(IServiceScope scope, object region, ContentTypeRegion regionType, bool managerInit) { if (region != null) { if (regionType.Fields.Count == 1) { // This region only has one field, that means // the region is in fact a field. await InitFieldAsync(scope, region, managerInit).ConfigureAwait(false); } else { // Initialize all fields foreach (var fieldType in regionType.Fields) { if (((IDictionary <string, object>)region).TryGetValue(fieldType.Id, out var field)) { await InitFieldAsync(scope, field, managerInit).ConfigureAwait(false); } } } } }