Esempio n. 1
0
        /// <summary>
        /// Maps a property to a CSV field.
        /// </summary>
        /// <param name="expression">The property to map.</param>
        /// <returns>The property mapping.</returns>
        public virtual CsvPropertyMap Map(Expression <Func <T, object> > expression)
        {
            var stack = ReflectionHelper.GetProperties(expression);

            if (stack.Count == 0)
            {
                throw new InvalidOperationException("No properties were found in expression '{expression}'.");
            }

            CsvClassMap  currentClassMap = this;
            PropertyInfo property;

            if (stack.Count > 1)
            {
                // We need to add a reference map for every sub property.
                while (stack.Count > 1)
                {
                    property = stack.Pop();
                    var mapType      = typeof(DefaultCsvClassMap <>).MakeGenericType(property.PropertyType);
                    var referenceMap = currentClassMap.References(mapType, property);
                    currentClassMap = referenceMap.Data.Mapping;
                }
            }

            // Add the property map to the last reference map.
            property = stack.Pop();

            return(currentClassMap.Map(property));
        }
Esempio n. 2
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="T:CsvHelper.Configuration.CsvPropertyReferenceMap" /> class.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="mapping">The <see cref="T:CsvHelper.Configuration.CsvClassMap" /> to use for the reference map.</param>
 public CsvPropertyReferenceMap(PropertyInfo property, CsvClassMap mapping)
 {
     if (mapping == null)
     {
         throw new ArgumentNullException("mapping");
     }
     Data = new CsvPropertyReferenceMapData(property, mapping);
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="member">The property/field.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvPropertyReferenceMap(MemberInfo member, CsvClassMap mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            data = new CsvPropertyReferenceMapData(member, mapping);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvParameterReferenceMap"/> class.
        /// </summary>
        /// <param name="parameter">The parameter.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvParameterReferenceMap(ParameterInfo parameter, CsvClassMap mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException(nameof(mapping));
            }

            data = new CsvParameterReferenceMapData(parameter, mapping);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvPropertyReferenceMap( PropertyInfo property, CsvClassMap mapping )
        {
            if( mapping == null )
            {
                throw new ArgumentNullException( "mapping" );
            }

            data = new CsvPropertyReferenceMapData( property, mapping );
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="member">The property/field.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvPropertyReferenceMap( MemberInfo member, CsvClassMap mapping )
        {
            if( mapping == null )
            {
                throw new ArgumentNullException( nameof( mapping ) );
            }

            data = new CsvPropertyReferenceMapData( member, mapping );
        }
Esempio n. 7
0
        /// <summary>
        /// Registers the class map.
        /// </summary>
        /// <param name="map">The class map to register.</param>
        public virtual void RegisterClassMap(CsvClassMap map)
        {
            if (map.Constructor == null && map.PropertyMaps.Count == 0 && map.ReferenceMaps.Count == 0)
            {
                throw new CsvConfigurationException("No mappings were specified in the CsvClassMap.");
            }

            Maps.Add(map);
        }
Esempio n. 8
0
        /// <summary>
        /// Use a <see cref="CsvClassMap"/> instance to configure mappings.
        /// When using a class map, no properties are mapped by default.
        /// Only properties specified in the mapping are used.
        /// </summary>
        public virtual void ClassMapping(CsvClassMap classMap)
        {
            if (classMap.Constructor == null && classMap.PropertyMaps.Count == 0 && classMap.ReferenceMaps.Count == 0)
            {
                throw new CsvConfigurationException("No mappings were specified in the CsvClassMap.");
            }

            Mapping = classMap;
        }
Esempio n. 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvPropertyReferenceMap(PropertyInfo property, CsvClassMap mapping)
        {
            if (mapping == null)
            {
                throw new ArgumentNullException("mapping");
            }

            this.property = property;
            Mapping       = mapping;
        }
Esempio n. 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="property">The property.</param>
        public CsvPropertyReferenceMap(Type type, PropertyInfo property)
        {
            if (type != typeof(CsvClassMap))
            {
                throw new ArgumentException("The type is not a CsvClassMap.");
            }

            this.property = property;
            Mapping       = (CsvClassMap)ReflectionHelper.CreateInstance(type);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="CsvPropertyReferenceMap"/> class.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="mapping">The <see cref="CsvClassMap"/> to use for the reference map.</param>
        public CsvPropertyReferenceMap( PropertyInfo property, CsvClassMap mapping )
        {
            if( mapping == null )
            {
                throw new ArgumentNullException( "mapping" );
            }

            this.property = property;
            Mapping = mapping;
        }
Esempio n. 12
0
        /// <summary>
        /// Maps a property to another class map.
        /// </summary>
        /// <param name="map">Instance map</param>
        /// <param name="expression">The expression.</param>
        /// <returns>The reference mapping for the property</returns>
        protected virtual CsvPropertyReferenceMap References(CsvClassMap map, Expression <Func <T, object> > expression)
        {
            var property = ReflectionHelper.GetProperty(expression);

            map.CreateMap();
            map.ReIndex(GetMaxIndex() + 1);
            var reference = new CsvPropertyReferenceMap(property, map);

            ReferenceMaps.Add(reference);
            return(reference);
        }
        /// <summary>
        ///     Adds the specified map for it's record type. If a map
        ///     already exists for the record type, the specified
        ///     map will replace it.
        /// </summary>
        /// <param name="map">The map.</param>
        internal virtual void Add(CsvClassMap map)
        {
            var type = GetGenericCsvClassMapType(map.GetType()).GetGenericArguments().First();

            if (data.ContainsKey(type))
            {
                data[type] = map;
                return;
            }
            data.Add(type, map);
        }
Esempio n. 14
0
        /// <summary>
        /// Adds the specified map for it's record type. If a map
        /// already exists for the record type, the specified
        /// map will replace it.
        /// </summary>
        /// <param name="map">The map.</param>
        public void Add(CsvClassMap map)
        {
            var type = GetGenericCsvClassMapType(map.GetType()).GetGenericArguments().First();

            if (data.ContainsKey(type))
            {
                data[type] = map;
            }
            else
            {
                data.Add(type, map);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Adds the specified map for it's record type. If a map
        /// already exists for the record type, the specified
        /// map will replace it.
        /// </summary>
        /// <param name="map">The map.</param>
        internal virtual void Add( CsvClassMap map )
        {
            var type = GetGenericCsvClassMapType( map.GetType() ).GetGenericArguments().First();

            if( data.ContainsKey( type ) )
            {
                data[type] = map;
            }
            else
            {
                data.Add( type, map );
            }
        }
Esempio n. 16
0
        /// <summary>
        ///     Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="ignoreReferences">
        ///     A value indicating if references should be ignored when auto mapping.
        ///     True to ignore references, otherwise false.
        /// </param>
        /// <param name="prefixReferenceHeaders">
        ///     A value indicating if headers of reference properties should
        ///     get prefixed by the parent property name.
        ///     True to prefix, otherwise false.
        /// </param>
        /// <param name="mapParents">The list of parents for the map.</param>
        internal static void AutoMapInternal(CsvClassMap map, bool ignoreReferences, bool prefixReferenceHeaders,
                                             LinkedList <Type> mapParents, int indexStart = 0)
        {
            var genericArguments = map.GetType().GetTypeInfo().BaseType.GetGenericArguments()[0];

            if (typeof(IEnumerable).IsAssignableFrom(genericArguments))
            {
                throw new CsvConfigurationException(
                          "Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?");
            }
            var properties = genericArguments.GetProperties(BindingFlags.Instance | BindingFlags.Public);

            for (int i = 0; i < properties.Length; i++)
            {
                var propertyInfo = properties[i];
                var type         = TypeConverterFactory.GetConverter(propertyInfo.PropertyType).GetType();
                if (type != typeof(EnumerableConverter))
                {
                    bool flag = type == typeof(DefaultTypeConverter);
                    if (!(flag & (propertyInfo.PropertyType.GetConstructor(new Type[0]) != null)))
                    {
                        var csvPropertyMap = new CsvPropertyMap(propertyInfo);
                        csvPropertyMap.Data.Index = map.GetMaxIndex() + 1;
                        if (csvPropertyMap.Data.TypeConverter.CanConvertFrom(typeof(string)) ||
                            csvPropertyMap.Data.TypeConverter.CanConvertTo(typeof(string)) && !flag)
                        {
                            map.PropertyMaps.Add(csvPropertyMap);
                        }
                    }
                    else if (!ignoreReferences && !CheckForCircularReference(propertyInfo.PropertyType, mapParents))
                    {
                        mapParents.AddLast(genericArguments);
                        var csvClassMap =
                            (CsvClassMap)
                            ReflectionHelper.CreateInstance(
                                typeof(DefaultCsvClassMap <>).MakeGenericType(propertyInfo.PropertyType));
                        AutoMapInternal(csvClassMap, false, prefixReferenceHeaders, mapParents, map.GetMaxIndex() + 1);
                        if (csvClassMap.PropertyMaps.Count > 0 || csvClassMap.ReferenceMaps.Count > 0)
                        {
                            var csvPropertyReferenceMap = new CsvPropertyReferenceMap(propertyInfo, csvClassMap);
                            if (prefixReferenceHeaders)
                            {
                                csvPropertyReferenceMap.Prefix(null);
                            }
                            map.ReferenceMaps.Add(csvPropertyReferenceMap);
                        }
                    }
                }
            }
            map.ReIndex(indexStart);
        }
Esempio n. 17
0
        /// <summary>
        /// Adds the specified map for it's record type. If a map
        /// already exists for the record type, the specified
        /// map will replace it.
        /// </summary>
        /// <param name="map">The map.</param>
        public void Add( CsvClassMap map )
        {
            #if WINRT_4_5
            var type = map.GetType().GetTypeInfo().BaseType.GenericTypeArguments.First();
            #else
            var type = map.GetType().BaseType.GetGenericArguments().First();
            #endif

            if( data.ContainsKey( type ) )
            {
                data[type] = map;
            }
            else
            {
                data.Add( type, map );
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Maps a property/field to a CSV field.
        /// </summary>
        /// <param name="expression">The property/field to map.</param>
        /// <param name="useExistingMap">If true, an existing map will be used if available.
        /// If false, a new map is created for the same property/field.</param>
        /// <returns>The property/field mapping.</returns>
        public virtual CsvPropertyMap Map(Expression <Func <T, object> > expression, bool useExistingMap = true)
        {
            var stack = ReflectionHelper.GetMembers(expression);

            if (stack.Count == 0)
            {
                throw new InvalidOperationException("No properties/fields were found in expression '{expression}'.");
            }

            CsvClassMap currentClassMap = this;
            MemberInfo  member;

            if (stack.Count > 1)
            {
                // We need to add a reference map for every sub property/field.
                while (stack.Count > 1)
                {
                    member = stack.Pop();
                    Type mapType;
                    var  property = member as PropertyInfo;
                    var  field    = member as FieldInfo;
                    if (property != null)
                    {
                        mapType = typeof(DefaultCsvClassMap <>).MakeGenericType(property.PropertyType);
                    }
                    else if (field != null)
                    {
                        mapType = typeof(DefaultCsvClassMap <>).MakeGenericType(field.FieldType);
                    }
                    else
                    {
                        throw new InvalidOperationException("The given expression was not a property or a field.");
                    }

                    var referenceMap = currentClassMap.References(mapType, member);
                    currentClassMap = referenceMap.Data.Mapping;
                }
            }

            // Add the property/field map to the last reference map.
            member = stack.Pop();

            return(currentClassMap.Map(member, useExistingMap));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CsvPropertyReferenceMapData"/> class.
 /// </summary>
 /// <param name="member">The property/field.</param>
 /// <param name="mapping">The mapping this is a reference for.</param>
 public CsvPropertyReferenceMapData(MemberInfo member, CsvClassMap mapping)
 {
     Member  = member;
     Mapping = mapping;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CsvParameterReferenceMapData"/> class.
 /// </summary>
 /// <param name="parameter">The parameter.</param>
 /// <param name="mapping">The mapping this is a reference for.</param>
 public CsvParameterReferenceMapData(ParameterInfo parameter, CsvClassMap mapping)
 {
     Parameter = parameter;
     Mapping   = mapping;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CsvPropertyReferenceMapData"/> class.
 /// </summary>
 /// <param name="member">The property/field.</param>
 /// <param name="mapping">The mapping this is a reference for.</param>
 public CsvPropertyReferenceMapData( MemberInfo member, CsvClassMap mapping )
 {
     Member = member;
     Mapping = mapping;
 }
Esempio n. 22
0
 /// <summary>
 /// Use a <see cref="CsvClassMap"/> instance to configure mappings.
 /// When using a class map, no properties are mapped by default.
 /// Only properties specified in the mapping are used.
 /// </summary>
 public void ClassMapping(CsvClassMap classMap)
 {
     properties = classMap.Properties;
 }
Esempio n. 23
0
        /// <summary>
        /// Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="options">Options for auto mapping.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        /// <param name="indexStart">The index starting point.</param>
        protected virtual void AutoMapProperties(CsvClassMap map, AutoMapOptions options, LinkedList <Type> mapParents, int indexStart = 0)
        {
            var type = map.GetGenericType();

            var flags = BindingFlags.Instance | BindingFlags.Public;

            if (options.IncludePrivateProperties)
            {
                flags = flags | BindingFlags.NonPublic;
            }

            var members = new List <MemberInfo>();

            if (options.MemberTypes.HasFlag(MemberTypes.Properties))
            {
                // We need to go up the declaration tree and find the actual type the property
                // exists on and use that PropertyInfo instead. This is so we can get the private
                // set method for the property.
                var properties = new List <PropertyInfo>();
                foreach (var property in type.GetProperties(flags))
                {
                    properties.Add(ReflectionHelper.GetDeclaringProperty(type, property, flags));
                }

                members.AddRange(properties);
            }

            if (options.MemberTypes.HasFlag(MemberTypes.Fields))
            {
                var fields = new List <MemberInfo>();
                foreach (var field in type.GetFields(flags))
                {
                    if (!field.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Any())
                    {
                        fields.Add(field);
                    }
                }

                members.AddRange(fields);
            }

            foreach (var member in members)
            {
                var typeConverterType = TypeConverterFactory.Current.GetConverter(member.MemberType()).GetType();

                if (options.HasHeaderRecord && enumerableConverters.Contains(typeConverterType))
                {
                    // Enumerable converters can't write the header properly, so skip it.
                    continue;
                }

                var memberTypeInfo     = member.MemberType().GetTypeInfo();
                var isDefaultConverter = typeConverterType == typeof(DefaultTypeConverter);
                if (isDefaultConverter && (memberTypeInfo.HasParameterlessConstructor() || memberTypeInfo.IsUserDefinedStruct()))
                {
                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.

                    if (options.IgnoreReferences)
                    {
                        continue;
                    }

                    if (CheckForCircularReference(member.MemberType(), mapParents))
                    {
                        continue;
                    }

                    mapParents.AddLast(type);
                    var refMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(member.MemberType());
                    var refMap     = (CsvClassMap)ReflectionHelper.CreateInstance(refMapType);
                    var refOptions = options.Copy();
                    refOptions.IgnoreReferences = false;
                    // Need to use Max here for nested types.
                    AutoMapProperties(refMap, options, mapParents, Math.Max(map.GetMaxIndex() + 1, indexStart));
                    mapParents.Drop(mapParents.Find(type));

                    if (refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0)
                    {
                        var referenceMap = new CsvPropertyReferenceMap(member, refMap);
                        if (options.PrefixReferenceHeaders)
                        {
                            referenceMap.Prefix();
                        }

                        map.ReferenceMaps.Add(referenceMap);
                    }
                }
                else
                {
                    var propertyMap = CsvPropertyMap.CreateGeneric(map.ClassType, member);
                    // Use global values as the starting point.
                    propertyMap.Data.TypeConverterOptions = TypeConverterOptions.Merge(new TypeConverterOptions(), options.TypeConverterOptionsFactory.GetOptions(member.MemberType()), propertyMap.Data.TypeConverterOptions);
                    propertyMap.Data.Index = map.GetMaxIndex() + 1;
                    if (!isDefaultConverter)
                    {
                        // Only add the property/field map if it can be converted later on.
                        // If the property/field will use the default converter, don't add it because
                        // we don't want the .ToString() value to be used when auto mapping.
                        map.PropertyMaps.Add(propertyMap);
                    }
                }
            }

            map.ReIndex(indexStart);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CsvPropertyReferenceMapData"/> class.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="mapping">The mapping this is a reference for.</param>
 public CsvPropertyReferenceMapData( PropertyInfo property, CsvClassMap mapping )
 {
     Property = property;
     Mapping = mapping;
 }
Esempio n. 25
0
        /// <summary>
        /// Auto maps the given map using constructor parameters.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="options">Options for auto mapping.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        /// <param name="indexStart">The index starting point.</param>
        protected virtual void AutoMapConstructorParameters(CsvClassMap map, AutoMapOptions options, LinkedList <Type> mapParents, int indexStart = 0)
        {
            var type        = map.GetGenericType();
            var constructor = options.GetConstructor(map.ClassType);
            var parameters  = constructor.GetParameters();

            foreach (var parameter in parameters)
            {
                var typeConverterType = TypeConverterFactory.Current.GetConverter(parameter.ParameterType).GetType();

                var parameterMap = new CsvParameterMap(parameter);

                var memberTypeInfo     = parameter.ParameterType.GetTypeInfo();
                var isDefaultConverter = typeConverterType == typeof(DefaultTypeConverter);
                if (isDefaultConverter && (memberTypeInfo.HasParameterlessConstructor() || memberTypeInfo.IsUserDefinedStruct()))
                {
                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.

                    if (options.IgnoreReferences)
                    {
                        throw new InvalidOperationException($"Configuration '{nameof( options.IgnoreReferences )}' can't be true " +
                                                            "when using types without a default constructor. Constructor parameters " +
                                                            "are used and all properties including references must be used.");
                    }

                    if (CheckForCircularReference(parameter.ParameterType, mapParents))
                    {
                        throw new InvalidOperationException($"A circular reference was detected in constructor paramter '{parameter.Name}'." +
                                                            "Since all parameters must be supplied for a constructor, this parameter can't be skipped.");
                    }

                    mapParents.AddLast(type);
                    var refMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(parameter.ParameterType);
                    var refMap     = (CsvClassMap)ReflectionHelper.CreateInstance(refMapType);
                    var refOptions = options.Copy();
                    refOptions.IgnoreReferences = false;
                    AutoMapProperties(refMap, options, mapParents, Math.Max(map.GetMaxIndex() + 1, indexStart));
                    mapParents.Drop(mapParents.Find(type));

                    var referenceMap = new CsvParameterReferenceMap(parameter, refMap);
                    if (options.PrefixReferenceHeaders)
                    {
                        referenceMap.Prefix();
                    }

                    parameterMap.ReferenceMap = referenceMap;
                }
                else if (options.ShouldUseConstructorParameters(parameter.ParameterType))
                {
                    mapParents.AddLast(type);
                    var constructorMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(parameter.ParameterType);
                    var constructorMap     = (CsvClassMap)ReflectionHelper.CreateInstance(constructorMapType);
                    var constructorOptions = options.Copy();
                    constructorOptions.IgnoreReferences = false;
                    // Need to use Max here for nested types.
                    AutoMapConstructorParameters(constructorMap, constructorOptions, mapParents, Math.Max(map.GetMaxIndex() + 1, indexStart));
                    mapParents.Drop(mapParents.Find(type));

                    parameterMap.ConstructorTypeMap = constructorMap;
                }
                else
                {
                    parameterMap.Data.TypeConverterOptions = TypeConverterOptions.Merge(new TypeConverterOptions(), options.TypeConverterOptionsFactory.GetOptions(parameter.ParameterType), parameterMap.Data.TypeConverterOptions);
                    parameterMap.Data.Index = map.GetMaxIndex() + 1;
                }

                map.ParameterMaps.Add(parameterMap);
            }

            map.ReIndex(indexStart);
        }
Esempio n. 26
0
        /// <summary>
        /// Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="ignoreReferences">A value indicating if references should be ignored when auto mapping.
        /// True to ignore references, otherwise false.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        internal static void AutoMapInternal(CsvClassMap map, bool ignoreReferences, LinkedList <Type> mapParents)
        {
#if WINRT_4_5
            var type = map.GetType().GetTypeInfo().BaseType.GetGenericArguments()[0];
#else
            var type = map.GetType().BaseType.GetGenericArguments()[0];
#endif

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                throw new CsvConfigurationException("Types that inhererit IEnumerable cannot be auto mapped. " +
                                                    "Did you accidentally call GetRecord or WriteRecord which " +
                                                    "acts on a single record instead of calling GetRecords or " +
                                                    "WriteRecords which acts on a list of records?");
            }

#if WINRT_4_5
            var properties = type.GetProperties();
#else
            var properties = type.GetProperties();
#endif
            foreach (var property in properties)
            {
                var isDefaultConverter = TypeConverterFactory.GetConverter(property.PropertyType).GetType() == typeof(DefaultTypeConverter);
#if WINRT_4_5
                var hasDefaultConstructor = property.PropertyType.GetTypeInfo().DeclaredConstructors.Any(c => !c.GetParameters().Any());
#else
                var hasDefaultConstructor = property.PropertyType.GetConstructor(Type.EmptyTypes) != null;
#endif
                if (isDefaultConverter && hasDefaultConstructor)
                {
                    if (ignoreReferences)
                    {
                        continue;
                    }

                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.
                    if (CheckForCircularReference(property.PropertyType, mapParents))
                    {
                        continue;
                    }

                    mapParents.AddLast(type);
                    var refMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(property.PropertyType);
                    var refMap     = (CsvClassMap)ReflectionHelper.CreateInstance(refMapType);
                    AutoMapInternal(refMap, false, mapParents);
                    if (refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0)
                    {
                        map.ReferenceMaps.Add(new CsvPropertyReferenceMap(property, refMap));
                    }
                }
                else
                {
                    var propertyMap = new CsvPropertyMap(property);
                    propertyMap.Data.Index = map.GetMaxIndex() + 1;
                    if (propertyMap.Data.TypeConverter.CanConvertFrom(typeof(string)) ||
                        propertyMap.Data.TypeConverter.CanConvertTo(typeof(string)) && !isDefaultConverter)
                    {
                        // Only add the property map if it can be converted later on.
                        // If the property will use the default converter, don't add it because
                        // we don't want the .ToString() value to be used when auto mapping.
                        map.PropertyMaps.Add(propertyMap);
                    }
                }
            }

            map.ReIndex();
        }
Esempio n. 27
0
 /// <summary>
 /// Use a <see cref="CsvClassMap"/> instance to configure mappings.
 /// When using a class map, no properties are mapped by default.
 /// Only properties specified in the mapping are used.
 /// </summary>
 public virtual void ClassMapping(CsvClassMap classMap)
 {
     Constructor = classMap.Constructor;
     properties  = classMap.PropertyMaps;
     references  = classMap.ReferenceMaps;
 }
Esempio n. 28
0
 /// <summary>
 /// Use a <see cref="CsvClassMap"/> instance to configure mappings.
 /// When using a class map, no properties are mapped by default.
 /// Only properties specified in the mapping are used.
 /// </summary>
 public virtual void ClassMapping(CsvClassMap classMap)
 {
     properties = classMap.PropertyMaps;
     references = classMap.ReferenceMaps;
 }
Esempio n. 29
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="T:CsvHelper.Configuration.CsvPropertyReferenceMapData" /> class.
 /// </summary>
 /// <param name="property">The property.</param>
 /// <param name="mapping">The mapping this is a reference for.</param>
 public CsvPropertyReferenceMapData(PropertyInfo property, CsvClassMap mapping)
 {
     Property = property;
     Mapping  = mapping;
 }
Esempio n. 30
0
        /// <summary>
        /// Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="options">Options for auto mapping.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        /// <param name="indexStart">The index starting point.</param>
        internal static void AutoMapInternal( CsvClassMap map, AutoMapOptions options, LinkedList<Type> mapParents, int indexStart = 0 )
        {
            var type = map.GetType().GetTypeInfo().BaseType.GetGenericArguments()[0];
            if( typeof( IEnumerable ).IsAssignableFrom( type ) )
            {
                throw new CsvConfigurationException( "Types that inherit IEnumerable cannot be auto mapped. " +
                                                     "Did you accidentally call GetRecord or WriteRecord which " +
                                                     "acts on a single record instead of calling GetRecords or " +
                                                     "WriteRecords which acts on a list of records?" );
            }

            var flags = BindingFlags.Instance | BindingFlags.Public;
            if( options.IncludePrivateProperties )
            {
                flags = flags | BindingFlags.NonPublic;
            }

            var members = new List<MemberInfo>();
            if( ( options.MemberTypes & MemberTypes.Properties ) == MemberTypes.Properties )
            {
                var properties = type.GetProperties( flags );
                members.AddRange( properties );
            }

            if( ( options.MemberTypes & MemberTypes.Fields ) == MemberTypes.Fields )
            {
                var fields = new List<MemberInfo>();
                foreach( var field in type.GetFields( flags ) )
                {
                    if( !field.GetCustomAttributes( typeof( CompilerGeneratedAttribute ), false ).Any() )
                    {
                        fields.Add( field );
                    }
                }

                members.AddRange( fields );
            }

            foreach( var member in members )
            {
                var typeConverterType = TypeConverterFactory.GetConverter( member.MemberType() ).GetType();

                if( typeConverterType == typeof( EnumerableConverter ) )
                {
                    // The IEnumerable converter just throws an exception so skip it.
                    continue;
                }

                var isDefaultConverter = typeConverterType == typeof( DefaultTypeConverter );
                var hasDefaultConstructor = member.MemberType().GetConstructor( new Type[0] ) != null;
                if( isDefaultConverter && hasDefaultConstructor )
                {
                    if( options.IgnoreReferences )
                    {
                        continue;
                    }

                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.
                    if( CheckForCircularReference( member.MemberType(), mapParents ) )
                    {
                        continue;
                    }

                    mapParents.AddLast( type );
                    var refMapType = typeof( DefaultCsvClassMap<> ).MakeGenericType( member.MemberType() );
                    var refMap = (CsvClassMap)ReflectionHelper.CreateInstance( refMapType );
                    var refOptions = options.Copy();
                    refOptions.IgnoreReferences = false;
                    AutoMapInternal( refMap, options, mapParents, map.GetMaxIndex() + 1 );

                    if( refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0 )
                    {
                        var referenceMap = new CsvPropertyReferenceMap( member, refMap );
                        if( options.PrefixReferenceHeaders )
                        {
                            referenceMap.Prefix();
                        }

                        map.ReferenceMaps.Add( referenceMap );
                    }
                }
                else
                {
                    var propertyMap = new CsvPropertyMap( member );
                    // Use global values as the starting point.
                    propertyMap.Data.TypeConverterOptions = TypeConverterOptions.Merge( options.TypeConverterOptionsFactory.GetOptions( member.MemberType() ) );
                    propertyMap.Data.Index = map.GetMaxIndex() + 1;
                    if( !isDefaultConverter )
                    {
                        // Only add the property/field map if it can be converted later on.
                        // If the property/field will use the default converter, don't add it because
                        // we don't want the .ToString() value to be used when auto mapping.
                        map.PropertyMaps.Add( propertyMap );
                    }
                }
            }

            map.ReIndex( indexStart );
        }
Esempio n. 31
0
        /// <summary>
        /// Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="options">Options for auto mapping.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        /// <param name="indexStart">The index starting point.</param>
        internal static void AutoMapInternal(CsvClassMap map, AutoMapOptions options, LinkedList <Type> mapParents, int indexStart = 0)
        {
            var type = map.GetType().GetTypeInfo().BaseType.GetGenericArguments()[0];

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                throw new CsvConfigurationException("Types that inherit IEnumerable cannot be auto mapped. " +
                                                    "Did you accidentally call GetRecord or WriteRecord which " +
                                                    "acts on a single record instead of calling GetRecords or " +
                                                    "WriteRecords which acts on a list of records?");
            }

            var flags = BindingFlags.Instance | BindingFlags.Public;

            if (options.IncludePrivateProperties)
            {
                flags = flags | BindingFlags.NonPublic;
            }

            var members = new List <MemberInfo>();

            if ((options.MemberTypes & MemberTypes.Properties) == MemberTypes.Properties)
            {
                var properties = type.GetProperties(flags);
                members.AddRange(properties);
            }

            if ((options.MemberTypes & MemberTypes.Fields) == MemberTypes.Fields)
            {
                var fields = new List <MemberInfo>();
                foreach (var field in type.GetFields(flags))
                {
                    if (!field.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Any())
                    {
                        fields.Add(field);
                    }
                }

                members.AddRange(fields);
            }

            foreach (var member in members)
            {
                var typeConverterType = TypeConverterFactory.GetConverter(member.MemberType()).GetType();

                if (typeConverterType == typeof(EnumerableConverter))
                {
                    // The IEnumerable converter just throws an exception so skip it.
                    continue;
                }

                var isDefaultConverter    = typeConverterType == typeof(DefaultTypeConverter);
                var hasDefaultConstructor = member.MemberType().GetConstructor(new Type[0]) != null;
                if (isDefaultConverter && hasDefaultConstructor)
                {
                    if (options.IgnoreReferences)
                    {
                        continue;
                    }

                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.
                    if (CheckForCircularReference(member.MemberType(), mapParents))
                    {
                        continue;
                    }

                    mapParents.AddLast(type);
                    var refMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(member.MemberType());
                    var refMap     = (CsvClassMap)ReflectionHelper.CreateInstance(refMapType);
                    var refOptions = options.Copy();
                    refOptions.IgnoreReferences = false;
                    AutoMapInternal(refMap, options, mapParents, map.GetMaxIndex() + 1);

                    if (refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0)
                    {
                        var referenceMap = new CsvPropertyReferenceMap(member, refMap);
                        if (options.PrefixReferenceHeaders)
                        {
                            referenceMap.Prefix();
                        }

                        map.ReferenceMaps.Add(referenceMap);
                    }
                }
                else
                {
                    var propertyMap = new CsvPropertyMap(member);
                    // Use global values as the starting point.
                    propertyMap.Data.TypeConverterOptions = TypeConverterOptions.Merge(options.TypeConverterOptionsFactory.GetOptions(member.MemberType()));
                    propertyMap.Data.Index = map.GetMaxIndex() + 1;
                    if (!isDefaultConverter)
                    {
                        // Only add the property/field map if it can be converted later on.
                        // If the property/field will use the default converter, don't add it because
                        // we don't want the .ToString() value to be used when auto mapping.
                        map.PropertyMaps.Add(propertyMap);
                    }
                }
            }

            map.ReIndex(indexStart);
        }
Esempio n. 32
0
 public ClassMapBuilder()
 {
     map = new BuilderClassMap <TClass>();
 }
Esempio n. 33
0
        /// <summary>
        /// Auto maps the given map and checks for circular references as it goes.
        /// </summary>
        /// <param name="map">The map to auto map.</param>
        /// <param name="ignoreReferences">A value indicating if references should be ignored when auto mapping.
        /// True to ignore references, otherwise false.</param>
        /// <param name="prefixReferenceHeaders">A value indicating if headers of reference properties should
        /// get prefixed by the parent property name.
        /// True to prefix, otherwise false.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        internal static void AutoMapInternal(CsvClassMap map, bool ignoreReferences, bool prefixReferenceHeaders, LinkedList <Type> mapParents, int indexStart = 0)
        {
            var type = map.GetType().BaseType.GetGenericArguments()[0];

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
                throw new CsvConfigurationException("Types that inhererit IEnumerable cannot be auto mapped. " +
                                                    "Did you accidentally call GetRecord or WriteRecord which " +
                                                    "acts on a single record instead of calling GetRecords or " +
                                                    "WriteRecords which acts on a list of records?");
            }

            var properties = type.GetProperties();

            foreach (var property in properties)
            {
                var typeConverterType = TypeConverterFactory.GetConverter(property.PropertyType).GetType();
                if (typeConverterType == typeof(EnumerableConverter))
                {
                    // The IEnumerable converter just throws an exception so skip it.
                    continue;
                }

                var isDefaultConverter    = typeConverterType == typeof(DefaultTypeConverter);
                var hasDefaultConstructor = property.PropertyType.GetConstructor(new Type[0]) != null;
                if (isDefaultConverter && hasDefaultConstructor)
                {
                    if (ignoreReferences)
                    {
                        continue;
                    }

                    // If the type is not one covered by our type converters
                    // and it has a parameterless constructor, create a
                    // reference map for it.
                    if (CheckForCircularReference(property.PropertyType, mapParents))
                    {
                        continue;
                    }

                    mapParents.AddLast(type);
                    var refMapType = typeof(DefaultCsvClassMap <>).MakeGenericType(property.PropertyType);
                    var refMap     = (CsvClassMap)ReflectionHelper.CreateInstance(refMapType);
                    AutoMapInternal(refMap, false, prefixReferenceHeaders, mapParents, map.GetMaxIndex() + 1);

                    if (prefixReferenceHeaders)
                    {
                        foreach (var propertyMap in refMap.PropertyMaps)
                        {
                            for (var i = 0; i < propertyMap.Data.Names.Count; i++)
                            {
                                propertyMap.Data.Names[i] = string.Format("{0}.{1}", property.Name, propertyMap.Data.Names[i]);
                            }
                        }
                    }

                    if (refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0)
                    {
                        map.ReferenceMaps.Add(new CsvPropertyReferenceMap(property, refMap));
                    }
                }
                else
                {
                    var propertyMap = new CsvPropertyMap(property);
                    propertyMap.Data.Index = map.GetMaxIndex() + 1;
                    if (propertyMap.Data.TypeConverter.CanConvertFrom(typeof(string)) ||
                        propertyMap.Data.TypeConverter.CanConvertTo(typeof(string)) && !isDefaultConverter)
                    {
                        // Only add the property map if it can be converted later on.
                        // If the property will use the default converter, don't add it because
                        // we don't want the .ToString() value to be used when auto mapping.
                        map.PropertyMaps.Add(propertyMap);
                    }
                }
            }

            map.ReIndex(indexStart);
        }
Esempio n. 34
0
 public PropertyMapBuilder(CsvClassMap <TClass> classMap, CsvPropertyMap <TClass, TProperty> propertyMap)
 {
     this.classMap    = classMap;
     this.propertyMap = propertyMap;
 }