/// <summary> /// Parsing CSV file contetnt to object T /// </summary> /// <typeparam name="T">Generic object</typeparam> /// <param name="data">CSV file content</param> /// <param name="delimiter">Delimiter char, used in CSV file</param> /// <param name="stringSplitOptions">Specifies whether applicable Overload:System.String.Split method overloads include or omit empty substrings from the return value.</param> /// <returns>List with T objects parsed from CSV</returns> public static List <T> ParseCsvToObject <T>(string data, char delimiter = ',', StringSplitOptions stringSplitOptions = StringSplitOptions.None) where T : new() { List <T> listOfObjects = new List <T>(); char[] separator = { delimiter }; using (StringReader reader = new StringReader(data)) { int lineNo = 0; string line = string.Empty; Dictionary <string, int> headerSet = new Dictionary <string, int>(); while ((line = reader.ReadLine()) != null) { string[] splittedLine = line.Split(separator, stringSplitOptions); if (++lineNo == 1) { for (int i = 0; i < splittedLine.Length; i++) { string currentColumnName = splittedLine[i]; headerSet.Add(currentColumnName, i); } } else { T parsedObject = new T(); PropertyInfo[] properties = typeof(T).GetProperties(); foreach (PropertyInfo property in properties) { ParserAttributes attribute = Attribute.GetCustomAttribute(property, typeof(ParserAttributes)) as ParserAttributes; if (attribute != null) { var currentColumn = headerSet.FirstOrDefault(header => header.Key == attribute.CsvName); if (currentColumn.Key != null) { int numberOfCurrentColumn = currentColumn.Value; string currentColumnValue = splittedLine[numberOfCurrentColumn]; Type propType = property.PropertyType; object convertedColumnValue = Convert.ChangeType(currentColumnValue, propType, CultureInfo.InvariantCulture); property.SetValue(parsedObject, convertedColumnValue); } } } listOfObjects.Add(parsedObject); } } } return(listOfObjects); }
/// <summary> /// Get PropertyInfo, which has attribute name equals to key /// </summary> /// <param name="propertyInfos">All PropertiesInfo in class</param> /// <param name="key">Attribute name</param> /// <returns>PropertyInfo for property with key attribute</returns> private PropertyInfo GetKeyPropertyInfoByCsvName(PropertyInfo[] propertyInfos, string key) { foreach (PropertyInfo property in propertyInfos) { ParserAttributes attribute = Attribute.GetCustomAttribute(property, typeof(ParserAttributes)) as ParserAttributes; if (attribute != null && attribute.CsvName.Equals(key)) { return(property); } } return(null); }
/// <summary> /// Comparation TBase and and TMergeData, to set empty properties in TBase /// </summary> /// <typeparam name="TMergeData"></typeparam> /// <typeparam name="TBase"></typeparam> /// <param name="data"></param> /// <param name="currentBaseRecord"></param> private void CompareTBaseAndTMergeDataAndFillEmptyProperties <TMergeData, TBase>(TMergeData data, TBase currentBaseRecord) { if (data != null) { foreach (PropertyInfo property in _propertiesOfBaseObject) { if (property != _keyPropertyOfBaseObject || property.GetValue(currentBaseRecord) == default) { ParserAttributes attribute = Attribute.GetCustomAttribute(property, typeof(ParserAttributes)) as ParserAttributes; SetBaseWithNewValueIfMergeDataContainsProperty(attribute, property, currentBaseRecord, data); } } } }
private void SetBaseWithNewValueIfMergeDataContainsProperty <TBase, TMergeData>(ParserAttributes attribute, PropertyInfo property, TBase currentBaseRecord, TMergeData data) { if (attribute != null) { foreach (PropertyInfo mergeProperty in _propertiesOfObjectToMerge) { if (mergeProperty != _keyPropertyOfMergeDataObject) { ParserAttributes mergeAttribute = Attribute.GetCustomAttribute(mergeProperty, typeof(ParserAttributes)) as ParserAttributes; if (mergeAttribute != null && attribute.CsvName.Equals(mergeAttribute.CsvName)) { var mergePropertyValue = mergeProperty.GetValue(data); property.SetValue(currentBaseRecord, mergePropertyValue); } } } } }