private static FormlyTemplateOptions?ResolveFormlyTemplateOptions(Type propertyType,
                                                                          Attribute[] attributes,
                                                                          FormlyGenerationSettings setting,
                                                                          Type type)
        {
            var templateOptions = new FormlyTemplateOptions
            {
                Label       = ResolveLabel(attributes),
                Required    = ResolveRequired(attributes),
                Placeholder = ResolvePlaceholder(attributes),
                Description = ResolveDescription(attributes),
                Min         = ResolveMin(attributes),
                Max         = ResolveMax(attributes),
                MinLength   = ResolveMinLength(attributes),
                MaxLength   = ResolveMaxLength(attributes),
                Pattern     = ResolvePattern(attributes),
                Disabled    = ResolveDisabled(attributes),
                Options     = ResolveOptions(propertyType, attributes, type),
                Type        = FormlyGenerationSettings.InputTypeResolver.Invoke(propertyType, attributes),
                Multiple    = ResolveMultiple(propertyType, attributes),
                Rows        = ResolveRows(attributes),
                AddonLeft   = ResolveAddonLeft(attributes),
                AddonRight  = ResolveAddonRight(attributes),
            };

            return(templateOptions.HasData() ? templateOptions : null);
        }
        private static FormlyFieldConfig BuildFormlyFieldConfig(PropertyInfo propertyInfo,
                                                                Attribute[] attributes,
                                                                FormlyGenerationSettings setting,
                                                                Type type,
                                                                string?parentKey)
        {
            var formlyFieldConfig = new FormlyFieldConfig
            {
                Key             = ResolveKey(parentKey, propertyInfo.Name, attributes),
                Type            = ResolveFieldType(propertyInfo.PropertyType, attributes),
                DefaultValue    = ResolveDefaultValue(attributes),
                TemplateOptions =
                    ResolveFormlyTemplateOptions(propertyInfo.PropertyType, attributes, setting, type),
                HideExpression       = ResolveHideExpression(attributes),
                ExpressionProperties = ResolveExpressionProperties(attributes),
                Validation           = ResolveValidation(attributes),
                Validators           = ResolveValidators(attributes),
                AsyncValidators      = ResolveAsyncValidators(attributes),
                Wrappers             = ResolveWrappers(attributes),
                ClassName            = ResolveClassName(attributes),
                FieldGroupClassName  = ResolveFieldGroupClassName(attributes),
                FieldGroup           = ResolveFieldGroup(propertyInfo, attributes, setting),
                FieldArray           = ResolveFieldArray(propertyInfo, setting),
            };

            return(formlyFieldConfig);
        }
        private static FormlyFieldConfigCollection FromType(Type type,
                                                            FormlyGenerationSettings setting,
                                                            string?parentKey)
        {
            if (Cache.TryGetValue(new CacheKey(type, parentKey), out FormlyFieldConfigCollection result))
            {
                return(result);
            }

            var bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            result = new FormlyFieldConfigCollection(type.GetProperties(bindingFlags)
                                                     .Select(propertyInfo => new
            {
                PropertyInfo = propertyInfo,
                Attributes   = Attribute.GetCustomAttributes(propertyInfo)
            })
                                                     .Where(x => !x.Attributes.Any(IsIgnoreAttribute))
                                                     .OrderBy(x => ResolveOrder(x.Attributes))
                                                     .SelectMany(x =>
            {
                IEnumerable <FormlyFieldConfig> fieldConfigs;
                if (IsInlineNestedFieldGroup(x.PropertyInfo, x.Attributes))
                {
                    var key      = ResolveKey(parentKey, x.PropertyInfo.Name, x.Attributes);
                    fieldConfigs = FromType(x.PropertyInfo.PropertyType, setting, key);
                    return(fieldConfigs);
                }

                fieldConfigs = new[]
                {
                    BuildFormlyFieldConfig(x.PropertyInfo, x.Attributes, setting, type, parentKey)
                };

                return(fieldConfigs);
            })
                                                     .ToList());

            var typeCustomAttributes = type.GetCustomAttributes();
            var fieldTypeAttribute   = typeCustomAttributes.OfType <FieldTypeAttribute>().FirstOrDefault();

            if (fieldTypeAttribute != null)
            {
                result = new FormlyFieldConfigCollection
                {
                    new FormlyFieldConfig
                    {
                        Type       = fieldTypeAttribute.Type,
                        FieldGroup = result
                    }
                };
            }

            Cache.TryAdd(new CacheKey(type, parentKey), result);

            return(result);
        }
 private static FormlyFieldConfigCollection?ResolveFieldGroup(PropertyInfo propertyInfo,
                                                              Attribute[] attributes,
                                                              FormlyGenerationSettings setting)
 {
     return(!propertyInfo.PropertyType.IsSimple() &&
            !propertyInfo.PropertyType.IsCollection() &&
            attributes.OfType <FieldGroupAttribute>().Any()
         ? FromType(propertyInfo.PropertyType, setting)
         : null);
 }
 public static FormlyFieldConfigCollection FromType(Type type, FormlyGenerationSettings setting) =>
 FromType(type, setting, null);
 public static FormlyFieldConfigCollection FromType <T>(FormlyGenerationSettings setting) =>
 FromType(typeof(T), setting);
        private static FormlyFieldConfig?ResolveFieldArray(PropertyInfo propertyInfo, FormlyGenerationSettings setting)
        {
            if (!propertyInfo.PropertyType.IsCollection())
            {
                return(null);
            }

            var elementType = propertyInfo.PropertyType.GetElementType() !;

            if (elementType.IsSimple())
            {
                return(BuildFormlyFieldConfigForSimpleArrayElement(elementType));
            }

            return(null); // TODO
        }