예제 #1
0
            public APrivateMap()
            {
                var options = new AutoMapOptions
                {
                    IncludePrivateMembers = true,
                    MemberTypes           = MemberTypes.Fields
                };

                AutoMap(options);
            }
예제 #2
0
 /// <summary>
 /// Auto maps all properties/fields for the given type. If a property/field 
 /// is mapped again it will override the existing map.
 /// </summary>
 /// <param name="options">Options for auto mapping.</param>
 public virtual void AutoMap( AutoMapOptions options )
 {
     var mapParents = new LinkedList<Type>();
     AutoMapInternal( this, options, mapParents );
 }
예제 #3
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 );
        }