/// <summary> /// Tries to map values from the row to the object using reflection. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="rowObj">The new object.</param> /// <param name="row">The row.</param> /// <param name="validator">The validator.</param> /// <param name="errors">The errors.</param> /// <exception cref="System.ArgumentNullException"> /// rowObj /// or /// row /// or /// validator /// or /// errors /// </exception> public static void TryMapValues <T>(T rowObj, dynamic row, IObjectValidator validator, ref List <string> errors) { if (rowObj == null) { throw new ArgumentNullException("rowObj"); } if (row == null) { throw new ArgumentNullException("row"); } if (validator == null) { throw new ArgumentNullException("validator"); } if (errors == null) { throw new ArgumentNullException("errors"); } CustomExpandoObject expando = row as CustomExpandoObject; if (expando == null) { expando = new CustomExpandoObject(row, true); } var getRowValueMethod = validator.GetType().GetMethods().First(x => x.Name == "GetRowValue" && x.GetParameters().Count() >= 5 && x.GetParameters().First().ParameterType == typeof(string)); PropertyInfo[] properties = typeof(T).GetProperties(); foreach (var prop in properties) { if (expando.ContainsKey(prop.Name)) //there may be properties that were not imported { string val = Convert.ToString(expando[prop.Name]); Type nonNullableType = FileIOHelpers.GetNonNullableType(prop.PropertyType); if (nonNullableType.IsValueType) { bool isNullable = Nullable.GetUnderlyingType(prop.PropertyType) != null; //convert the Helpers.GetValue method into a generic method of the same type as the property var genericGetvalueMethod = getRowValueMethod.MakeGenericMethod(new Type[] { nonNullableType }); var value = genericGetvalueMethod.Invoke(validator, new object[] { val, errors, null, isNullable, prop.Name }); prop.SetValue(rowObj, value, null); //this should use the setrowvalue that outputs conversion errors } else { prop.SetValue(rowObj, Convert.ChangeType(val, prop.PropertyType), null); } } } }
/// <summary> /// Maps the object. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="row">The row.</param> /// <param name="rowIndex">Index of the row.</param> /// <param name="validator">The validator.</param> /// <param name="mapper">The mapper.</param> /// <param name="errors">The errors.</param> /// <returns>T.</returns> /// <exception cref="System.ArgumentNullException"> /// row /// or /// validator /// or /// errors /// </exception> public static T MapObject <T>(dynamic row, int rowIndex, IObjectValidator validator, FileValuesMap <T> mapper, ref List <string> errors) { if (row == null) { throw new ArgumentNullException("row"); } if (validator == null) { throw new ArgumentNullException("validator"); } if (errors == null) { throw new ArgumentNullException("errors"); } //if the object is not a dynamic object we do not need to recreate it, just use as is if (!FileIOHelpers.IsDynamicType(row)) { return(row); } T rowObj = (T)Activator.CreateInstance(typeof(T), true); IFileRowMapper mapperObj = null; //a custom mapper. will take priority if exists if (mapper != null) { mapper.Invoke(ref rowObj, rowIndex, row, validator, ref errors); } else if ((mapperObj = rowObj as IFileRowMapper) != null) { mapperObj.MapValues(rowIndex, row, validator, ref errors); } else { //last ditch effort to map the values to the object if neither of the main mappers gets called TryMapValues <T>(rowObj, row, validator, ref errors); } return(rowObj); }