Ejemplo n.º 1
0
        public static bool AutoMapClass <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> classMap)
        {
            Type type = typeof(T);

            if (type.GetTypeInfo().IsInterface)
            {
                classMap = null;
                return(false);
            }

            var map = new ExcelClassMap <T>();
            IEnumerable <MemberInfo> properties = type.GetRuntimeProperties().Where(p => p.CanWrite);
            IEnumerable <MemberInfo> fields     = type.GetRuntimeFields().Where(f => f.IsPublic);

            foreach (MemberInfo member in properties.Concat(fields))
            {
                Type       memberType = member.MemberType();
                MethodInfo method     = MappingMethod.MakeGenericMethod(memberType);

                var  parameters = new object[] { member, emptyValueStrategy, null };
                bool result     = (bool)method.Invoke(null, parameters);
                if (!result)
                {
                    classMap = null;
                    return(false);
                }

                map.Mappings.Add((ExcelPropertyMap)parameters[2]);
            }

            classMap = map;
            return(true);
        }
Ejemplo n.º 2
0
        public void MapObject_ClassMapFactory_ReturnsExpected()
        {
            var map = new TestClassMap(FallbackStrategy.ThrowIfPrimitive);
            ExcelClassMap <string> mapping = map.MapObject(t => t.Value);

            Assert.Empty(mapping.Properties);
        }
Ejemplo n.º 3
0
        public void Ctor_Type()
        {
            var map = new ExcelClassMap(typeof(string));

            Assert.Equal(typeof(string), map.Type);
            Assert.Empty(map.Properties);
            Assert.Same(map.Properties, map.Properties);
        }
Ejemplo n.º 4
0
        public void Map_MultipleMemberAccessTypeAlreadyMapped_ThrowsInvalidOperationException()
        {
            var iconvertibleType = new IConvertibleType();
            var classMap         = new ExcelClassMap <IConvertibleValue>();

            classMap.Map(p => p.IConvertibleType);

            Assert.Throws <InvalidOperationException>(() => classMap.Map(p => p.IConvertibleType.Value));
        }
 public void TryGetClassMap_NullClassType_ThrowsArgumentNullException()
 {
     using (var importer = Helpers.GetImporter("Primitives.xlsx"))
     {
         ExcelClassMap classMap = null;
         Assert.Throws <ArgumentNullException>("classType", () => importer.Configuration.TryGetClassMap(null, out classMap));
         Assert.Null(classMap);
     }
 }
 public void RegisterClassMapsInNamespace_NoAssemblyAndValidNamespaceString_ReturnsExpected()
 {
     using (var importer = Helpers.GetImporter("Strings.xlsx"))
     {
         IEnumerable <ExcelClassMap> classMaps = ExcelImporterUtils.RegisterClassMapsInNamespace(importer, "ExcelMapper.Utilities.Tests");
         ExcelClassMap classMap = Assert.Single(classMaps);
         Assert.IsType <TestClassMap>(classMap);
     }
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Adds the properties from the mapping. This will recursively
 /// traverse the mapping tree and add all properties for
 /// reference maps.
 /// </summary>
 /// <param name="properties">The properties to be added to.</param>
 /// <param name="mapping">The mapping where the properties are added from.</param>
 protected void AddProperties(
     ExcelPropertyMapCollection properties,
     ExcelClassMap mapping)
 {
     properties.AddRange(mapping.PropertyMaps);
     foreach (var refMap in mapping.ReferenceMaps)
     {
         AddProperties(properties, refMap.Mapping);
     }
 }
        public void WithClassMap_ClassMap_ReturnsExpected()
        {
            var        classMap     = new ExcelClassMap <string>();
            MemberInfo propertyInfo = typeof(TestClass).GetProperty(nameof(TestClass.Value));

            var propertyMap = new ObjectExcelPropertyMap <string>(propertyInfo, new ExcelClassMap <string>());

            Assert.Same(propertyMap, propertyMap.WithClassMap(classMap));
            Assert.Same(classMap, propertyMap.ClassMap);
        }
        public void WithClassMap_NullClassMap_ThrowsArgumentNullException()
        {
            var        classMap     = new ExcelClassMap <string>();
            MemberInfo propertyInfo = typeof(TestClass).GetProperty(nameof(TestClass.Value));
            var        propertyMap  = new ObjectExcelPropertyMap <string>(propertyInfo, new ExcelClassMap <string>())
            {
                ClassMap = classMap
            };

            Assert.Throws <ArgumentNullException>("classMap", () => propertyMap.WithClassMap((ExcelClassMap <string>)null));
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates a class map for the given type using the given strategy.
        /// </summary>
        /// <param name="emptyValueStrategy">The default strategy to use when the value of a cell is empty.</param>
        /// <param name="classMap">The class map for the given type.</param>
        /// <returns>True if the class map could be created, else false.</returns>
        public static bool TryCreateClassMap <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> classMap)
        {
            if (!Enum.IsDefined(typeof(FallbackStrategy), emptyValueStrategy))
            {
                throw new ArgumentException($"Invalid value \"{emptyValueStrategy}\".", nameof(emptyValueStrategy));
            }

            Type type = typeof(T);

            if (type.GetTypeInfo().IsInterface)
            {
                classMap = null;
                return(false);
            }

            var map = new ExcelClassMap <T>(emptyValueStrategy);
            IEnumerable <MemberInfo> properties = type.GetRuntimeProperties().Where(p => p.CanWrite && p.SetMethod.IsPublic && !p.SetMethod.IsStatic);
            IEnumerable <MemberInfo> fields     = type.GetRuntimeFields().Where(f => f.IsPublic && !f.IsStatic);

            foreach (MemberInfo member in properties.Concat(fields))
            {
                // Ignore this property/field.
                if (Attribute.IsDefined(member, typeof(ExcelIgnoreAttribute)))
                {
                    continue;
                }

                // Infer the mapping for each member (property/field) belonging to the type.
                Type       memberType = member.MemberType();
                MethodInfo method     = TryCreateMemberMapMethod.MakeGenericMethod(memberType);
                if (memberType == type)
                {
                    throw new ExcelMappingException($"Cannot map recursive property \"{member.Name}\" of type {memberType}. Consider applying the ExcelIgnore attribute.");
                }

                var  parameters = new object[] { member, emptyValueStrategy, null };
                bool result     = (bool)method.Invoke(null, parameters);
                if (!result)
                {
                    classMap = null;
                    return(false);
                }

                // Get the out parameter representing the property map for the member.
                map.Properties.Add(new ExcelPropertyMap(member, (IMap)parameters[2]));
            }

            classMap = map;
            return(true);
        }
Ejemplo n.º 11
0
        /// <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);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Creates the property bindings for the given <see cref="ExcelClassMap"/>.
        /// </summary>
        /// <param name="mapping">The mapping to create the bindings for.</param>
        /// <param name="bindings">The bindings that will be added to from the mapping.</param>
        private void CreatePropertyBindingsForMapping(
            ExcelClassMap mapping,
            List <MemberBinding> bindings)
        {
            // First bind all the regular properties for this record
            AddPropertyBindings(mapping.PropertyMaps, bindings);

            // Now process each reference map to map embedded classes
            foreach (var referenceMap in mapping.ReferenceMaps)
            {
                // Ignore any maps we cannot read
                if (!CanRead(referenceMap))
                {
                    continue;
                }

                // Now map all the properties in this reference map
                var referenceBindings = new List <MemberBinding>();
                CreatePropertyBindingsForMapping(referenceMap.Mapping, referenceBindings);
                var referenceBody = Expression.MemberInit(Expression.New(referenceMap.Property.PropertyType), referenceBindings);
                bindings.Add(Expression.Bind(referenceMap.Property, referenceBody));
            }
        }
Ejemplo n.º 13
0
        internal static bool TryCreateObjectMap <T>(FallbackStrategy emptyValueStrategy, out ExcelClassMap <T> mapping)
        {
            if (!TryCreateClassMap(emptyValueStrategy, out ExcelClassMap <T> excelClassMap))
            {
                mapping = null;
                return(false);
            }

            mapping = excelClassMap;
            return(true);
        }
Ejemplo n.º 14
0
        public void WithClassMap_InvokeClassMap_Success()
        {
            var map = new ExcelClassMap <Helpers.TestClass>();

            Assert.Same(this, WithClassMap(map));
        }