private void DiscoverRecordFields(Type recordType)
 {
     RecordFieldConfigurations.Clear();
     foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(recordType).AsTypedEnumerable <PropertyDescriptor>().Where(pd => pd.Attributes.OfType <ChoCSVRecordFieldAttribute>().Any()))
     {
         var obj = new ChoCSVRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoCSVRecordFieldAttribute>().First());
         obj.FieldType = pd.PropertyType;
         RecordFieldConfigurations.Add(obj);
     }
 }
        public override void Validate()
        {
            if (RecordFieldConfigurations.Count > 0)
            {
                MaxFieldPosition = RecordFieldConfigurations.Max(r => r.FieldPosition);
            }
            else
            {
                throw new ChoRecordConfigurationException("No record fields specified.");
            }
            RecordFieldConfigurationsDict = RecordFieldConfigurations.Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name);

            if (Delimiter.IsNullOrWhiteSpace())
            {
                Delimiter = Culture.TextInfo.ListSeparator;
                if (Delimiter.IsNullOrWhiteSpace())
                {
                    Delimiter = ",";
                }
            }

            base.Validate();

            if (Delimiter.IsNullOrWhiteSpace())
            {
                throw new ChoRecordConfigurationException("Delimiter can't be null or whitespace.");
            }
            if (Delimiter == EOLDelimiter)
            {
                throw new ChoRecordConfigurationException("Delimiter [{0}] can't be same as EODDelimiter [{1}]".FormatString(Delimiter, EOLDelimiter));
            }
            if (Delimiter.Contains(QuoteChar))
            {
                throw new ChoRecordConfigurationException("QuoteChar [{0}] can't be one of Delimiter characters [{1}]".FormatString(QuoteChar, Delimiter));
            }
            if (Comments.Contains(Delimiter))
            {
                throw new ChoRecordConfigurationException("One of the Comments contains Delimiter. Not allowed.");
            }

            //Validate Header
            if (CSVFileHeaderConfiguration != null)
            {
                CSVFileHeaderConfiguration.Validate(this);
            }

            //Validate each record field
            foreach (var fieldConfig in RecordFieldConfigurations)
            {
                fieldConfig.Validate(this);
            }

            if (!CSVFileHeaderConfiguration.HasHeaderRecord)
            {
                //Check if any field has 0
                if (RecordFieldConfigurations.Where(i => i.FieldPosition <= 0).Count() > 0)
                {
                    throw new ChoRecordConfigurationException("Some fields contain invalid field position. All field positions must be > 0.");
                }

                //Check field position for duplicate
                int[] dupPositions = RecordFieldConfigurations.GroupBy(i => i.FieldPosition)
                                     .Where(g => g.Count() > 1)
                                     .Select(g => g.Key).ToArray();

                if (dupPositions.Length > 0)
                {
                    throw new ChoRecordConfigurationException("Duplicate field positions [Index: {0}] specified to record fields.".FormatString(String.Join(",", dupPositions)));
                }
            }
            else
            {
                //Check if any field has empty names
                if (RecordFieldConfigurations.Where(i => i.FieldName.IsNullOrWhiteSpace()).Count() > 0)
                {
                    throw new ChoRecordConfigurationException("Some fields has empty field name specified.");
                }

                //Check field names for duplicate
                string[] dupFields = RecordFieldConfigurations.GroupBy(i => i.FieldName, CSVFileHeaderConfiguration.StringComparer)
                                     .Where(g => g.Count() > 1)
                                     .Select(g => g.Key).ToArray();

                if (dupFields.Length > 0)
                {
                    throw new ChoRecordConfigurationException("Duplicate field names [Name: {0}] specified to record fields.".FormatString(String.Join(",", dupFields)));
                }
            }
        }
        public override void Validate(object state)
        {
            base.Validate(state);

            if (Delimiter.IsNullOrWhiteSpace())
                throw new ChoRecordConfigurationException("Delimiter can't be null or whitespace.");
            if (Delimiter == EOLDelimiter)
                throw new ChoRecordConfigurationException("Delimiter [{0}] can't be same as EODDelimiter [{1}]".FormatString(Delimiter, EOLDelimiter));
            if (Delimiter.Contains(QuoteChar))
                throw new ChoRecordConfigurationException("QuoteChar [{0}] can't be one of Delimiter characters [{1}]".FormatString(QuoteChar, Delimiter));
            if (Comments.Contains(Delimiter))
                throw new ChoRecordConfigurationException("One of the Comments contains Delimiter. Not allowed.");

            //Validate Header
            if (CSVFileHeaderConfiguration != null)
                CSVFileHeaderConfiguration.Validate(this);

            string[] headers = state as string[];
            if (AutoDiscoverColumns
                && RecordFieldConfigurations.Count == 0 && headers != null)
            {
                int index = 0;
                RecordFieldConfigurations = (from header in headers
                                             select new ChoCSVRecordFieldConfiguration(header, ++index)).ToList();
            }

            if (RecordFieldConfigurations.Count > 0)
                MaxFieldPosition = RecordFieldConfigurations.Max(r => r.FieldPosition);
            else
                throw new ChoRecordConfigurationException("No record fields specified.");

            RecordFieldConfigurationsDict = RecordFieldConfigurations.Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name);

            //Validate each record field
            foreach (var fieldConfig in RecordFieldConfigurations)
                fieldConfig.Validate(this);

            if (!CSVFileHeaderConfiguration.HasHeaderRecord)
            {
                //Check if any field has 0 
                if (RecordFieldConfigurations.Where(i => i.FieldPosition <= 0).Count() > 0)
                    throw new ChoRecordConfigurationException("Some fields contain invalid field position. All field positions must be > 0.");

                //Check field position for duplicate
                int[] dupPositions = RecordFieldConfigurations.GroupBy(i => i.FieldPosition)
                    .Where(g => g.Count() > 1)
                    .Select(g => g.Key).ToArray();

                if (dupPositions.Length > 0)
                    throw new ChoRecordConfigurationException("Duplicate field positions [Index: {0}] specified to record fields.".FormatString(String.Join(",", dupPositions)));
            }
            else
            {
                //Check if any field has empty names 
                if (RecordFieldConfigurations.Where(i => i.FieldName.IsNullOrWhiteSpace()).Count() > 0)
                    throw new ChoRecordConfigurationException("Some fields has empty field name specified.");

                //Check field names for duplicate
                string[] dupFields = RecordFieldConfigurations.GroupBy(i => i.FieldName, CSVFileHeaderConfiguration.StringComparer)
                    .Where(g => g.Count() > 1)
                    .Select(g => g.Key).ToArray();

                if (dupFields.Length > 0)
                    throw new ChoRecordConfigurationException("Duplicate field names [Name: {0}] specified to record fields.".FormatString(String.Join(",", dupFields)));
            }
        }