public void Item_SetNull_ThrowsArgumentNullException() { MemberInfo propertyInfo = typeof(TestClass).GetProperty(nameof(TestClass.Property)); var map = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap = new ExcelPropertyMap(propertyInfo, map); ExcelPropertyMapCollection mappings = new TestClassMap().Properties; mappings.Add(propertyMap); Assert.Throws <ArgumentNullException>("item", () => mappings[0] = null); }
/// <summary> /// Checks if the property can be written. /// </summary> /// <param name="propertyMap">The property map that we are checking.</param> /// <returns>A value indicating if the property can be written. /// True if the property can be written, otherwise false.</returns> protected bool CanWrite( ExcelPropertyMap propertyMap) { var cantWrite = // Ignored properties propertyMap.Data.Ignore || // Properties that don't have a public getter and we are honoring the accessor modifier propertyMap.Data.Property.GetGetMethod() == null && !_configuration.IgnorePrivateAccessor || // Properties that don't have a getter at all propertyMap.Data.Property.GetGetMethod(true) == null; return(!cantWrite); }
public void Item_SetValidItem_GetReturnsExpected() { MemberInfo propertyInfo = typeof(TestClass).GetProperty(nameof(TestClass.Property)); var map1 = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap1 = new ExcelPropertyMap(propertyInfo, map1); var map2 = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap2 = new ExcelPropertyMap(propertyInfo, map2); ExcelPropertyMapCollection mappings = new TestClassMap().Properties; mappings.Add(propertyMap1); mappings[0] = propertyMap2; Assert.Same(propertyMap2, mappings[0]); }
/// <summary> /// Determines if the property for the <see cref="ExcelPropertyMap"/> /// can be read. /// </summary> /// <param name="propertyMap">The property map.</param> /// <returns>A value indicating of the property can be read. True if it can, otherwise false.</returns> private bool CanRead( ExcelPropertyMap propertyMap) { var cantRead = // Write only properties. propertyMap.Data.WriteOnly || // Ignored properties. propertyMap.Data.Ignore || // Properties that don't have a public setter and we are honoring the accessor modifier. propertyMap.Data.Property.GetSetMethod() == null && !_configuration.IgnorePrivateAccessor || // Properties that don't have a setter at all. propertyMap.Data.Property.GetSetMethod(true) == null; return(!cantRead); }
public void Ctor_FieldInfoMember_Success() { MemberInfo fieldInfo = typeof(ClassWithEvent).GetField(nameof(ClassWithEvent._field)); var map = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap = new ExcelPropertyMap(fieldInfo, map); Assert.Same(fieldInfo, propertyMap.Member); Assert.Same(map, propertyMap.Map); var instance = new ClassWithEvent(); propertyMap.SetValueFactory(instance, 10); Assert.Equal(10, instance._field); }
/// <summary> /// Creates a property expression for the given property on the record. /// This will recursively traverse the mapping to find the property /// and create a safe property accessor for each level as it goes. /// </summary> /// <param name="recordExpression">The current property expression.</param> /// <param name="mapping">The mapping to look for the property to map on.</param> /// <param name="propertyMap">The property map to look for on the mapping.</param> /// <returns>An Expression to access the given property.</returns> protected Expression CreatePropertyExpression( Expression recordExpression, ExcelClassMap mapping, ExcelPropertyMap propertyMap) { // Handle the simple case where the property is on this level. if (mapping.PropertyMaps.Any(pm => pm == propertyMap)) { return(Expression.Property(recordExpression, propertyMap.Data.Property)); } // The property isn't on this level of the mapping. We need to search down through the reference maps. foreach (var refMap in mapping.ReferenceMaps) { // Recursively find the property access expression for this property var wrapped = Expression.Property(recordExpression, refMap.Property); var propertyExpression = CreatePropertyExpression(wrapped, refMap.Mapping, propertyMap); if (propertyExpression == null) { // Not in this reference map, try the next one continue; } // Build an expression that looks like this for value types: // // (record.RefMap == null) ? return new type() : record.RefMap.Property // // and like this for nullable types: // // (record.RefMap == null) ? return null : record.RefMap.Property // // So that the properties of the reference mapped object will be written as null or a default value // if the reference map is not present in the record being written var nullCheckExpression = Expression.Equal(wrapped, Expression.Constant(null)); var isValueType = propertyMap.Data.Property.PropertyType.IsValueType; var defaultValueExpression = isValueType ? (Expression)Expression.New(propertyMap.Data.Property.PropertyType) : Expression.Constant(null, propertyMap.Data.Property.PropertyType); var conditionExpression = Expression.Condition(nullCheckExpression, defaultValueExpression, propertyExpression); return(conditionExpression); } // We get here if the property did not match anything in this mapping return(null); }
public void Insert_ValidItem_Success() { MemberInfo propertyInfo = typeof(TestClass).GetProperty(nameof(TestClass.Property)); var map1 = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap1 = new ExcelPropertyMap(propertyInfo, map1); var map2 = new OneToOneMap <int>(new ColumnNameValueReader("Property")); var propertyMap2 = new ExcelPropertyMap(propertyInfo, map2); ExcelPropertyMapCollection mappings = new TestClassMap().Properties; mappings.Insert(0, propertyMap1); Assert.Same(propertyMap1, Assert.Single(mappings)); Assert.Same(propertyMap1, mappings[0]); mappings.Insert(0, propertyMap2); Assert.Equal(2, mappings.Count); Assert.Same(propertyMap2, mappings[0]); mappings.Insert(1, propertyMap1); Assert.Equal(3, mappings.Count); Assert.Same(propertyMap1, mappings[1]); }
private static bool InferMapping <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out ExcelPropertyMap mapping) { if (member.AutoMap(emptyValueStrategy, out SingleExcelPropertyMap <T> singleMapping)) { mapping = singleMapping; return(true); } if (member.MemberType().GetElementTypeOrEnumerableType(out Type elementType)) { MethodInfo method = AutoMapEnumerableMethod.MakeGenericMethod(elementType); var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (result) { mapping = (ExcelPropertyMap)parameters[2]; return(true); } } if (member.AutoMapObject(emptyValueStrategy, out ObjectExcelPropertyMap <T> objectMapping)) { mapping = objectMapping; return(true); } mapping = null; return(false); }
private static bool TryMapEnumerable(MemberInfo member, FallbackStrategy emptyValueStrategy, out ExcelPropertyMap map) { if (!member.MemberType().GetElementTypeOrEnumerableType(out Type elementType)) { map = null; return(false); } MethodInfo method = TryMapEnumerableMethod.MakeGenericMethod(elementType); var parameters = new object[] { member, emptyValueStrategy, null }; bool result = (bool)method.Invoke(null, parameters); if (result) { map = (ExcelPropertyMap)parameters[2]; return(true); } map = null; return(false); }
private static bool InferMapping <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out ExcelPropertyMap map) { // First, check if this is a well-known type (e.g. string/int). // This is a simple conversion from the cell's value to the type. if (TryMapPrimitive(member, emptyValueStrategy, out SingleExcelPropertyMap <T> singleMap)) { map = singleMap; return(true); } // Secondly, check if this is a collection (e.g. array, list). // This requires converting each value to the element type of the collection. if (TryMapEnumerable(member, emptyValueStrategy, out ExcelPropertyMap multiMap)) { map = multiMap; return(true); } // Thirdly, check if this is an object. // This requires converting each member and setting it on the object. if (TryMapObject(member, emptyValueStrategy, out ObjectExcelPropertyMap <T> objectMap)) { map = objectMap; return(true); } map = null; return(false); }