internal ChoKVPRecordFieldConfiguration GetFieldConfiguration(string propertyName, ChoKVPRecordFieldAttribute attr = null, Attribute[] otherAttrs = null)
        {
            if (!KVPRecordFieldConfigurations.Any(fc => fc.Name == propertyName))
            {
                KVPRecordFieldConfigurations.Add(new ChoKVPRecordFieldConfiguration(propertyName, attr, otherAttrs));
            }

            return(KVPRecordFieldConfigurations.First(fc => fc.Name == propertyName));
        }
 private void DiscoverRecordFields(Type recordType, string declaringMember, bool optIn = false)
 {
     if (!recordType.IsDynamicType())
     {
         Type pt = null;
         if (optIn) //ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType<ChoKVPRecordFieldAttribute>().Any()).Any())
         {
             foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType))
             {
                 pt = pd.PropertyType.GetUnderlyingType();
                 if (!pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt))
                 {
                     DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn);
                 }
                 else if (pd.Attributes.OfType <ChoKVPRecordFieldAttribute>().Any())
                 {
                     var obj = new ChoKVPRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoKVPRecordFieldAttribute>().First(), pd.Attributes.OfType <Attribute>().ToArray());
                     obj.FieldType          = pt;
                     obj.PropertyDescriptor = pd;
                     obj.DeclaringMember    = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name);
                     if (!KVPRecordFieldConfigurations.Any(c => c.Name == pd.Name))
                     {
                         KVPRecordFieldConfigurations.Add(obj);
                     }
                 }
             }
         }
         else
         {
             foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType))
             {
                 pt = pd.PropertyType.GetUnderlyingType();
                 if (pt != typeof(object) && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt))
                 {
                     DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn);
                 }
                 else
                 {
                     var obj = new ChoKVPRecordFieldConfiguration(pd.Name);
                     obj.FieldType          = pt;
                     obj.PropertyDescriptor = pd;
                     obj.DeclaringMember    = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name);
                     StringLengthAttribute slAttr = pd.Attributes.OfType <StringLengthAttribute>().FirstOrDefault();
                     if (slAttr != null && slAttr.MaximumLength > 0)
                     {
                         obj.Size = slAttr.MaximumLength;
                     }
                     DisplayAttribute dpAttr = pd.Attributes.OfType <DisplayAttribute>().FirstOrDefault();
                     if (dpAttr != null)
                     {
                         if (!dpAttr.ShortName.IsNullOrWhiteSpace())
                         {
                             obj.FieldName = dpAttr.ShortName;
                         }
                         else if (!dpAttr.Name.IsNullOrWhiteSpace())
                         {
                             obj.FieldName = dpAttr.Name;
                         }
                     }
                     DisplayFormatAttribute dfAttr = pd.Attributes.OfType <DisplayFormatAttribute>().FirstOrDefault();
                     if (dfAttr != null && !dfAttr.DataFormatString.IsNullOrWhiteSpace())
                     {
                         obj.FormatText = dfAttr.DataFormatString;
                     }
                     if (dfAttr != null && !dfAttr.NullDisplayText.IsNullOrWhiteSpace())
                     {
                         obj.NullValue = dfAttr.NullDisplayText;
                     }
                     if (!KVPRecordFieldConfigurations.Any(c => c.Name == pd.Name))
                     {
                         KVPRecordFieldConfigurations.Add(obj);
                     }
                 }
             }
         }
     }
 }