Example #1
0
        private static bool TryCreateDictionaryMap <T>(FallbackStrategy emptyValueStrategy, out IMap map)
        {
            // We should be able to parse anything that implements IEnumerable<KeyValuePair<TKey, TValue>>
            if (!typeof(T).ImplementsGenericInterface(typeof(IEnumerable <>), out Type keyValuePairType))
            {
                map = null;
                return(false);
            }
            if (!keyValuePairType.IsGenericType || keyValuePairType.GetGenericTypeDefinition() != typeof(KeyValuePair <,>))
            {
                map = null;
                return(false);
            }

            Type[]     arguments = keyValuePairType.GenericTypeArguments;
            Type       keyType   = arguments[0];
            Type       valueType = arguments[1];
            MethodInfo method    = TryCreateGenericDictionaryMapMethod.MakeGenericMethod(keyType, valueType);

            var  parameters = new object[] { typeof(T), emptyValueStrategy, null };
            bool result     = (bool)method.Invoke(null, parameters);

            if (result)
            {
                map = (IMap)parameters[2];
                return(true);
            }

            map = null;
            return(false);
        }
Example #2
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);
        }
Example #3
0
        public static bool AutoMapEnumerable <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out EnumerableExcelPropertyMap <T> map)
        {
            Type     rawType     = member.MemberType();
            TypeInfo rawTypeInfo = rawType.GetTypeInfo();

            if (!member.AutoMap(emptyValueStrategy, out SingleExcelPropertyMap <T> elementMapping))
            {
                map = null;
                return(false);
            }

            if (rawType.IsArray)
            {
                map = new ArrayPropertyMap <T>(member, elementMapping);
                return(true);
            }
            else if (rawTypeInfo.IsInterface)
            {
                if (rawTypeInfo.IsAssignableFrom(typeof(List <T>).GetTypeInfo()))
                {
                    map = new InterfaceAssignableFromListPropertyMap <T>(member, elementMapping);
                    return(true);
                }
            }
            else if (rawType.ImplementsInterface(typeof(ICollection <T>)))
            {
                map = new ConcreteICollectionPropertyMap <T>(rawType, member, elementMapping);
                return(true);
            }

            map = null;
            return(false);
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
 public SerializationContext(FallbackStrategy fallbackStrategy, IEnumerable <Type> types) : this(fallbackStrategy)
 {
     foreach (var type in types)
     {
         Register(type);
     }
 }
        public void Ctor_EmptyValueStrategy(FallbackStrategy emptyValueStrategy)
        {
            var map = new TestClassMap(emptyValueStrategy);

            Assert.Equal(emptyValueStrategy, map.EmptyValueStrategy);
            Assert.Equal(typeof(Helpers.TestClass), map.Type);
        }
Example #8
0
        /// <summary>
        /// Constructs a new class map for the given type using the given default strategy to use
        /// when the value of a cell is empty.
        /// </summary>
        /// <param name="emptyValueStrategy">The default strategy to use when the value of a cell is empty.</param>
        public ExcelClassMap(FallbackStrategy emptyValueStrategy) : this()
        {
            if (!Enum.IsDefined(typeof(FallbackStrategy), emptyValueStrategy))
            {
                throw new ArgumentException($"Invalid value \"{emptyValueStrategy}\".", nameof(emptyValueStrategy));
            }

            EmptyValueStrategy = emptyValueStrategy;
        }
Example #9
0
 private InProvider BuildProvider(FallbackStrategy fallbackStrategy = null, string fallbackLanguage = null)
 {
     return(new InBuilder()
            .AddJsonFile(TestUtils.DataJsonEnFile1, TestUtils.DataJsonEnLanguageCode, true)
            .AddJsonFile(TestUtils.DataJsonViFile1, TestUtils.DataJsonViLanguageCode)
            .SetFallbackStrategy(fallbackStrategy ?? FallbackStrategy.DefaultFallbackStrategy)
            .SetFallbackLanguage(fallbackLanguage ?? "en")
            .Build());
 }
Example #10
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);
        }
Example #11
0
        public static bool AutoMapObject <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out ObjectExcelPropertyMap <T> mapping)
        {
            if (!AutoMapClass(emptyValueStrategy, out ExcelClassMap <T> excelClassMap))
            {
                mapping = null;
                return(false);
            }

            mapping = new ObjectExcelPropertyMap <T>(member, excelClassMap);
            return(true);
        }
Example #12
0
        public static bool TryMapPrimitive <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out SingleExcelPropertyMap <T> map)
        {
            if (!GetWellKnownMapper(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback))
            {
                map = null;
                return(false);
            }

            map = new SingleExcelPropertyMap <T>(member)
                  .WithCellValueMappers(mapper)
                  .WithEmptyFallbackItem(emptyFallback)
                  .WithInvalidFallbackItem(invalidFallback);
            return(true);
        }
Example #13
0
        public static bool AutoMap <T>(this MemberInfo member, FallbackStrategy emptyValueStrategy, out SingleExcelPropertyMap <T> mapping)
        {
            if (!typeof(T).AutoMap(emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback))
            {
                mapping = null;
                return(false);
            }

            mapping = new SingleExcelPropertyMap <T>(member)
                      .WithCellValueMappers(mapper)
                      .WithEmptyFallbackItem(emptyFallback)
                      .WithInvalidFallbackItem(invalidFallback);
            return(true);
        }
Example #14
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);
        }
Example #15
0
        internal static bool TryCreatePrimitivePipeline <T>(FallbackStrategy emptyValueStrategy, out ValuePipeline <T> pipeline)
        {
            if (!TryGetWellKnownMap(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback))
            {
                pipeline = null;
                return(false);
            }

            pipeline = new ValuePipeline <T>();
            pipeline.AddCellValueMapper(mapper);
            pipeline.EmptyFallback   = emptyFallback;
            pipeline.InvalidFallback = invalidFallback;
            return(true);
        }
        public void TryCreateClassMap_ValidType_ReturnsTrue(FallbackStrategy emptyValueStrategy)
        {
            Assert.True(AutoMapper.TryCreateClassMap <TestClass>(emptyValueStrategy, out ExcelClassMap <TestClass> classMap));
            Assert.Equal(emptyValueStrategy, classMap.EmptyValueStrategy);
            Assert.Equal(typeof(TestClass), classMap.Type);
            Assert.Equal(5, classMap.Properties.Count);

            IEnumerable <string> members = classMap.Properties.Select(m => m.Member.Name);

            Assert.Contains("_inheritedField", members);
            Assert.Contains("_field", members);
            Assert.Contains("InheritedProperty", members);
            Assert.Contains("Property", members);
            Assert.Contains("PrivateGetProperty", members);
        }
Example #17
0
        internal static bool TryCreatePrimitiveMap <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out OneToOneMap <T> map)
        {
            if (!TryGetWellKnownMap(typeof(T), emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback))
            {
                map = null;
                return(false);
            }

            ISingleCellValueReader defaultReader = GetDefaultSingleCellValueReader(member);

            map = new OneToOneMap <T>(defaultReader)
                  .WithCellValueMappers(mapper)
                  .WithEmptyFallbackItem(emptyFallback)
                  .WithInvalidFallbackItem(invalidFallback);
            return(true);
        }
Example #18
0
        internal static bool TryAutoMap <T>(FallbackStrategy emptyValueStrategy, out IMap result)
        {
            // First see if we can create a dictionary map of this type.
            if (TryCreateDictionaryMap <T>(emptyValueStrategy, out IMap dictionaryMap))
            {
                result = dictionaryMap;
                return(true);
            }
            else if (TryCreateClassMap(emptyValueStrategy, out ExcelClassMap <T> classMap))
            {
                result = classMap;
                return(true);
            }

            result = null;
            return(false);
        }
Example #19
0
        private static bool TryCreateEnumerableMap(MemberInfo member, FallbackStrategy emptyValueStrategy, out IMap map)
        {
            if (!member.MemberType().GetElementTypeOrEnumerableType(out Type elementType))
            {
                map = null;
                return(false);
            }

            MethodInfo method = TryCreateGenericEnumerableMapMethod.MakeGenericMethod(elementType);

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

            if (result)
            {
                map = (IMap)parameters[2];
                return(true);
            }

            map = null;
            return(false);
        }
Example #20
0
        public static bool TryMapGenericEnumerable <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out EnumerableExcelPropertyMap <T> map)
        {
            Type     rawType     = member.MemberType();
            TypeInfo rawTypeInfo = rawType.GetTypeInfo();

            // First, get the mapper for the element. This is used to convert individual values
            // to be added to/included in the collection.
            if (!TryMapPrimitive(member, emptyValueStrategy, out SingleExcelPropertyMap <T> elementMapping))
            {
                map = null;
                return(false);
            }

            // Secondly, find the right way of adding the converted value to the collection.
            if (rawType.IsArray)
            {
                // Add values using the arrray indexer.
                map = new ArrayPropertyMap <T>(member, elementMapping);
                return(true);
            }
            else if (rawTypeInfo.IsInterface)
            {
                // Add values by creating a list and assigning to the property.
                if (rawTypeInfo.IsAssignableFrom(typeof(List <T>).GetTypeInfo()))
                {
                    map = new InterfaceAssignableFromListPropertyMap <T>(member, elementMapping);
                    return(true);
                }
            }
            else if (rawType.ImplementsInterface(typeof(ICollection <T>)))
            {
                // Add values using the ICollection<T>.Add method.
                map = new ConcreteICollectionPropertyMap <T>(rawType, member, elementMapping);
                return(true);
            }

            map = null;
            return(false);
        }
Example #21
0
        private static bool TryCreateMemberMap <T>(MemberInfo member, FallbackStrategy emptyValueStrategy, out IMap 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 (TryCreatePrimitiveMap(member, emptyValueStrategy, out OneToOneMap <T> singleMap))
            {
                map = singleMap;
                return(true);
            }

            // Secondly, check if this is a dictionary.
            // This requires converting each value to the value type of the collection.
            if (TryCreateDictionaryMap <T>(emptyValueStrategy, out IMap dictionaryMap))
            {
                map = dictionaryMap;
                return(true);
            }

            // Thirdly, check if this is a collection (e.g. array, list).
            // This requires converting each value to the element type of the collection.
            if (TryCreateEnumerableMap(member, emptyValueStrategy, out IMap multiMap))
            {
                map = multiMap;
                return(true);
            }

            // Fourthly, check if this is an object.
            // This requires converting each member and setting it on the object.
            if (TryCreateObjectMap(emptyValueStrategy, out ExcelClassMap <T> objectMap))
            {
                map = objectMap;
                return(true);
            }

            map = null;
            return(false);
        }
Example #22
0
 public SerializationContext(FallbackStrategy fallbackStrategy) : this()
 {
     this.fallbackStrategy = fallbackStrategy;
 }
Example #23
0
 public SerializationContext()
 {
     this.fallbackStrategy        = FallbackStrategy.DynamicObject;
     this.serializerObjectFactory = new SerializerObjectFactory();
     this.objectWrapperFactory    = new ObjectWrapperFactory(this);
 }
Example #24
0
        private static bool AutoMap(this Type memberType, FallbackStrategy emptyValueStrategy, out ICellValueMapper mapper, out IFallbackItem emptyFallback, out IFallbackItem invalidFallback)
        {
            Type type = memberType.GetNullableTypeOrThis(out bool isNullable);

            Type[] interfaces = type.GetTypeInfo().ImplementedInterfaces.ToArray();

            IFallbackItem ReconcileFallback(FallbackStrategy strategyToPursue, bool empty)
            {
                // Empty nullable values should be set to null.
                if (empty && isNullable)
                {
                    return(new FixedValueFallback(null));
                }
                else if (strategyToPursue == FallbackStrategy.SetToDefaultValue || emptyValueStrategy == FallbackStrategy.SetToDefaultValue)
                {
                    return(new FixedValueFallback(type.DefaultValue()));
                }
                else
                {
                    Debug.Assert(emptyValueStrategy == FallbackStrategy.ThrowIfPrimitive);

                    // The user specified that we should set to the default value if it was empty.
                    return(new ThrowFallback());
                }
            }

            if (type == typeof(DateTime))
            {
                mapper          = new DateTimeMapper();
                emptyFallback   = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false);
            }
            else if (type == typeof(bool))
            {
                mapper          = new BoolMapper();
                emptyFallback   = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false);
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                mapper          = new EnumMapper(type);
                emptyFallback   = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false);
            }
            else if (type == typeof(string) || type == typeof(object) || type == typeof(IConvertible))
            {
                mapper          = new StringMapper();
                emptyFallback   = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: false);
            }
            else if (type == typeof(Uri))
            {
                mapper          = new UriMapper();
                emptyFallback   = ReconcileFallback(FallbackStrategy.SetToDefaultValue, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false);
            }
            else if (interfaces.Any(t => t == typeof(IConvertible)))
            {
                mapper          = new ChangeTypeMapper(type);
                emptyFallback   = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: true);
                invalidFallback = ReconcileFallback(FallbackStrategy.ThrowIfPrimitive, empty: false);
            }
            else
            {
                mapper          = null;
                emptyFallback   = null;
                invalidFallback = null;
                return(false);
            }

            return(true);
        }
Example #25
0
        internal static bool TryCreateGenericEnumerableMap <TElement>(MemberInfo member, FallbackStrategy emptyValueStrategy, out ManyToOneEnumerableMap <TElement> map)
        {
            // First, get the pipeline for the element. This is used to convert individual values
            // to be added to/included in the collection.
            if (!TryCreatePrimitivePipeline <TElement>(emptyValueStrategy, out ValuePipeline <TElement> elementMapping))
            {
                map = null;
                return(false);
            }

            // Secondly, find the right way of adding the converted value to the collection.
            if (!TryGetCreateElementsFactory <TElement>(member.MemberType(), out CreateElementsFactory <TElement> factory))
            {
                map = null;
                return(false);
            }

            // Default to splitting.
            var defaultNameReader = GetDefaultSingleCellValueReader(member);
            var defaultReader     = new CharSplitCellValueReader(defaultNameReader);

            map = new ManyToOneEnumerableMap <TElement>(defaultReader, elementMapping, factory);
            return(true);
        }
Example #26
0
 public void Ctor_InvalidEmptyValueStrategy_ThrowsArgumentException(FallbackStrategy emptyValueStrategy)
 {
     Assert.Throws <ArgumentException>("emptyValueStrategy", () => new TestClassMap(emptyValueStrategy));
 }
Example #27
0
        internal static bool TryCreateGenericDictionaryMap <TKey, TValue>(Type memberType, FallbackStrategy emptyValueStrategy, out ManyToOneDictionaryMap <TValue> map)
        {
            if (!TryCreatePrimitivePipeline <TValue>(emptyValueStrategy, out ValuePipeline <TValue> valuePipeline))
            {
                map = null;
                return(false);
            }

            if (!TryGetCreateDictionaryFactory <TKey, TValue>(memberType, out CreateDictionaryFactory <TValue> factory))
            {
                map = null;
                return(false);
            }

            // Default to all columns.
            var defaultReader = new AllColumnNamesValueReader();

            map = new ManyToOneDictionaryMap <TValue>(defaultReader, valuePipeline, factory);
            return(true);
        }
 public SerializationContext(FallbackStrategy fallbackStrategy) : this()
 {
     this.fallbackStrategy = fallbackStrategy;
 }
Example #29
0
 public InBuilder SetFallbackStrategy(FallbackStrategy fallbackStrategy)
 {
     this.FallbackStrategy = fallbackStrategy;
     return(this);
 }
 public SerializationContext()
 {
     this.fallbackStrategy = FallbackStrategy.DynamicObject;
     this.serializerObjectFactory = new SerializerObjectFactory();
     this.objectWrapperFactory = new ObjectWrapperFactory(this);
 }
 public void TryCreateClassMap_InvalidFallbackStrategy_ThrowsArgumentException(FallbackStrategy emptyValueStrategy)
 {
     Assert.Throws <ArgumentException>("emptyValueStrategy", () => AutoMapper.TryCreateClassMap <IConvertible>(emptyValueStrategy, out _));
 }
 public SerializationContext(FallbackStrategy fallbackStrategy, IEnumerable<Type> types) : this(fallbackStrategy)
 {
     foreach (var type in types)
         Register(type);
 }
Example #33
0
 public TestClassMap(FallbackStrategy emptyValueStrategy) : base(emptyValueStrategy)
 {
 }