public void GetConverterForCharTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(char));

            Assert.IsInstanceOfType(converter, typeof(CharConverter));
        }
        public void GetConverterForUnknownTypeTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(TestUnknownClass));

            Assert.IsInstanceOfType(converter, typeof(DefaultTypeConverter));
        }
        public void GetConverterForByteTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(byte));

            Assert.IsInstanceOfType(converter, typeof(ByteConverter));
        }
Beispiel #4
0
        /// <inheritdoc/>
        public async Task <int> SaveSettingsAsync <T>(T settings, int storeId = 0) where T : ISettings, new()
        {
            Guard.NotNull(settings, nameof(settings));

            // INFO: Let SettingService's hook handler handle cache invalidation

            var settingsType = typeof(T);
            var prefix       = settingsType.Name;
            var hasChanges   = false;

            using var db = _dbContextFactory.CreateDbContext();
            var rawSettings = await GetRawSettingsAsync(db, settingsType, storeId, false, true);

            foreach (var prop in FastProperty.GetProperties(settingsType).Values)
            {
                // Get only properties we can read and write to
                if (!prop.IsPublicSettable)
                {
                    continue;
                }

                var converter = TypeConverterFactory.GetConverter(prop.Property.PropertyType);
                if (converter == null || !converter.CanConvertFrom(typeof(string)))
                {
                    continue;
                }

                string key          = prefix + "." + prop.Name;
                string currentValue = prop.GetValue(settings).Convert <string>();

                if (rawSettings.TryGetValue(key, out var setting))
                {
                    if (setting.Value != currentValue)
                    {
                        // Update
                        setting.Value = currentValue;
                        hasChanges    = true;
                    }
                }
                else
                {
                    // Insert
                    setting = new Setting
                    {
                        Name    = key.ToLowerInvariant(),
                        Value   = currentValue,
                        StoreId = storeId
                    };

                    hasChanges = true;
                    db.Settings.Add(setting);
                }
            }

            var numSaved = hasChanges ? await db.SaveChangesAsync() : 0;

            if (numSaved > 0)
            {
                // Prevent reloading from DB on next hit
                await _cache.PutAsync(
                    SettingService.BuildCacheKeyForClassAccess(settingsType, storeId),
                    settings,
                    new CacheEntryOptions().ExpiresIn(SettingService.DefaultExpiry));
            }

            return(numSaved);
        }
        public void GetConverterForEnumTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(TestEnum));

            Assert.IsInstanceOfType(converter, typeof(EnumConverter));
        }
        public void GetConverterForFloatTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(float));

            Assert.IsInstanceOfType(converter, typeof(SingleConverter));
        }
Beispiel #7
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 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 = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (var property in properties)
            {
                //如果存在ExportIgnoreAttribute,则跳过
                var exportIgnoreAttribute = property.GetAttribute <ExportIgnoreAttribute>();
                if (exportIgnoreAttribute != null)
                {
                    continue;
                }

                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 (refMap.PropertyMaps.Count > 0 || refMap.ReferenceMaps.Count > 0)
                    {
                        var referenceMap = new CsvPropertyReferenceMap(property, refMap);
                        if (prefixReferenceHeaders)
                        {
                            referenceMap.Prefix();
                        }

                        map.ReferenceMaps.Add(referenceMap);
                    }
                }
                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);
        }
        public void GetConverterForInt32Test()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(int));

            Assert.IsInstanceOfType(converter, typeof(Int32Converter));
        }
        public void GetConverterForNullableTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(int?));

            Assert.IsInstanceOfType(converter, typeof(NullableConverter));
        }
Beispiel #10
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 memberTypeInfo        = member.MemberType().GetTypeInfo();
                var isDefaultConverter    = typeConverterType == typeof(DefaultTypeConverter);
                var hasDefaultConstructor = member.MemberType().GetConstructor(new Type[0]) != null;
                var isUserDefinedStruct   = memberTypeInfo.IsValueType && !memberTypeInfo.IsPrimitive && !memberTypeInfo.IsEnum;
                if (isDefaultConverter && (hasDefaultConstructor || isUserDefinedStruct))
                {
                    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 = CsvPropertyMap.CreateGeneric(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);
        }
Beispiel #11
0
        /// <summary>
        /// Generates a <see cref="CsvClassMap"/> for the type.
        /// This internal method is used to pass extra information
        /// along so circular references can be checked, and
        /// property maps can be auto indexed.
        /// </summary>
        /// <param name="type">The type to generate for the map.</param>
        /// <param name="indexStart">The index that is started from.</param>
        /// <param name="mapParents">The list of parents for the map.</param>
        /// <returns></returns>
        internal virtual CsvClassMap AutoMapInternal(Type type, int indexStart, LinkedList <Type> mapParents)
        {
            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 (maps[type] != null)
            {
                // If the map already exists, use it.
                return(maps[type]);
            }

#if WINRT_4_5
            var properties = type.GetProperties();
#else
            var properties = type.GetProperties(propertyBindingFlags);
#endif
            var mapType = typeof(DefaultCsvClassMap <>).MakeGenericType(type);
            var map     = (CsvClassMap)ReflectionHelper.CreateInstance(mapType);
            map.IndexStart = indexStart;
            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 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 refMap = AutoMapInternal(property.PropertyType, map.GetMaxIndex(), 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);
                    }
                }
            }

            return(map);
        }
        /// <summary>
        /// Writes the field to the CSV file
        /// using the given <see cref="ITypeConverter"/>.
        /// When all fields are written for a record,
        /// <see cref="IWriter.NextRecord" /> must be called
        /// to complete writing of the current record.
        /// </summary>
        /// <typeparam name="T">The type of the field.</typeparam>
        /// <typeparam name="TConverter">The type of the converter.</typeparam>
        /// <param name="field">The field to write.</param>
        public virtual void WriteField <T, TConverter>(T field)
        {
            var converter = TypeConverterFactory.GetConverter <TConverter>();

            WriteField(field, converter);
        }
Beispiel #13
0
        /// Load settings
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        public virtual T LoadSetting <T>() where T : ISettings, new()
        {
            if (typeof(T).HasAttribute <JsonPersistAttribute>(true))
            {
                return(LoadSettingsJson <T>());
            }

            var settings = Activator.CreateInstance <T>();

            foreach (var fastProp in FastProperty.GetProperties(typeof(T)).Values)
            {
                var prop = fastProp.Property;

                // get properties we can read and write to
                if (!prop.CanWrite)
                {
                    continue;
                }

                var key = typeof(T).Name + "." + prop.Name;

                string setting = GetSettingByKey <string>(key);

                if (setting == null && !fastProp.IsSequenceType)
                {
                    #region Obsolete ('EnumerableConverter' can handle this case now)
                    //if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
                    //{
                    //	// convenience: don't return null for simple list types
                    //	var listArg = prop.PropertyType.GetGenericArguments()[0];
                    //	object list = null;

                    //	if (listArg == typeof(int))
                    //		list = new List<int>();
                    //	else if (listArg == typeof(decimal))
                    //		list = new List<decimal>();
                    //	else if (listArg == typeof(string))
                    //		list = new List<string>();

                    //	if (list != null)
                    //	{
                    //		fastProp.SetValue(settings, list);
                    //	}
                    //}
                    #endregion

                    continue;
                }

                var converter = TypeConverterFactory.GetConverter(prop.PropertyType);

                if (converter == null || !converter.CanConvertFrom(typeof(string)))
                {
                    continue;
                }

                object value = converter.ConvertFrom(setting);

                //set property
                fastProp.SetValue(settings, value);
            }

            return(settings);
        }
Beispiel #14
0
        public virtual T LoadSetting <T>(int storeId = 0) where T : ISettings, new()
        {
            if (typeof(T).HasAttribute <JsonPersistAttribute>(true))
            {
                return(LoadSettingsJson <T>(storeId));
            }

            var settings = Activator.CreateInstance <T>();

            var prefix = typeof(T).Name;

            foreach (var fastProp in FastProperty.GetProperties(typeof(T)).Values)
            {
                var prop = fastProp.Property;

                // get properties we can read and write to
                if (!prop.CanWrite)
                {
                    continue;
                }

                var key = prefix + "." + prop.Name;
                // load by store
                string setting = GetSettingByKey <string>(key, storeId: storeId, loadSharedValueIfNotFound: true);

                if (setting == null)
                {
                    if (fastProp.IsSequenceType)
                    {
                        if ((fastProp.GetValue(settings) as IEnumerable) != null)
                        {
                            // Instance of IEnumerable<> was already created, most likely in the constructor of the settings concrete class.
                            // In this case we shouldn't let the EnumerableConverter create a new instance but keep this one.
                            continue;
                        }
                    }
                    else
                    {
                        #region Obsolete ('EnumerableConverter' can handle this case now)
                        //if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
                        //{
                        //	// convenience: don't return null for simple list types
                        //	var listArg = prop.PropertyType.GetGenericArguments()[0];
                        //	object list = null;

                        //	if (listArg == typeof(int))
                        //		list = new List<int>();
                        //	else if (listArg == typeof(decimal))
                        //		list = new List<decimal>();
                        //	else if (listArg == typeof(string))
                        //		list = new List<string>();

                        //	if (list != null)
                        //	{
                        //		fastProp.SetValue(settings, list);
                        //	}
                        //}
                        #endregion

                        continue;
                    }
                }

                var converter = TypeConverterFactory.GetConverter(prop.PropertyType);

                if (converter == null || !converter.CanConvertFrom(typeof(string)))
                {
                    continue;
                }

                try
                {
                    object value = converter.ConvertFrom(setting);

                    // Set property
                    fastProp.SetValue(settings, value);
                }
                catch (Exception ex)
                {
                    var msg = "Could not convert setting '{0}' to type '{1}'".FormatInvariant(key, prop.PropertyType.Name);
                    Logger.Error(ex, msg);
                }
            }

            return(settings);
        }
        public void GetConverterForDecimalTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(decimal));

            Assert.IsInstanceOfType(converter, typeof(DecimalConverter));
        }
        public void GetConverterForStringTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(string));

            Assert.IsInstanceOfType(converter, typeof(StringConverter));
        }
        public void GetConverterForDoubleTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(double));

            Assert.IsInstanceOfType(converter, typeof(DoubleConverter));
        }
        public void GetConverterForUInt16Test()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(ushort));

            Assert.IsInstanceOfType(converter, typeof(UInt16Converter));
        }
        public void GetConverterForGuidTest()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(Guid));

            Assert.IsInstanceOfType(converter, typeof(GuidConverter));
        }
        public void GetConverterForUInt64Test()
        {
            var converter = TypeConverterFactory.GetConverter(typeof(ulong));

            Assert.IsInstanceOfType(converter, typeof(UInt64Converter));
        }
Beispiel #21
0
 private EnumReader(IColumnReader valueReader, IColumnReader rowIndexReader)
 {
     _valueReader            = valueReader;
     _rowIndexReader         = rowIndexReader;
     _rowIndexToIntConverter = TypeConverterFactory.GetConverter(typeof(byte), typeof(int));
 }
Beispiel #22
0
        private ISettings MaterializeSettings(Type settingsType, IDictionary <string, Setting> rawSettings)
        {
            Guard.NotNull(settingsType, nameof(settingsType));
            Guard.NotNull(rawSettings, nameof(rawSettings));

            var instance = (ISettings)Activator.CreateInstance(settingsType);
            var prefix   = settingsType.Name;

            foreach (var fastProp in FastProperty.GetProperties(settingsType).Values)
            {
                var prop = fastProp.Property;

                // Get properties we can read and write to
                if (!prop.CanWrite)
                {
                    continue;
                }

                string key = prefix + "." + prop.Name;
                rawSettings.TryGetValue(key, out var rawSetting);

                string setting = rawSetting?.Value;

                if (setting == null)
                {
                    if (fastProp.IsSequenceType)
                    {
                        if ((fastProp.GetValue(instance) as System.Collections.IEnumerable) != null)
                        {
                            // Instance of IEnumerable<> was already created, most likely in the constructor of the settings concrete class.
                            // In this case we shouldn't let the EnumerableConverter create a new instance but keep this one.
                            continue;
                        }
                    }
                    else
                    {
                        continue;
                    }
                }

                var converter = TypeConverterFactory.GetConverter(prop.PropertyType);

                if (converter == null || !converter.CanConvertFrom(typeof(string)))
                {
                    continue;
                }

                try
                {
                    object value = converter.ConvertFrom(setting);

                    // Set property
                    fastProp.SetValue(instance, value);
                }
                catch (Exception ex)
                {
                    var msg = "Could not convert setting '{0}' to type '{1}'".FormatInvariant(key, prop.PropertyType.Name);
                    Logger.Error(ex, msg);
                }
            }

            return(instance);
        }