/// <summary> /// Updates settings for a store. /// </summary> /// <param name="settings">Settings class instance.</param> /// <param name="form">Form value collection.</param> /// <param name="storeId">Store identifier.</param> /// <param name="settingService">Setting service.</param> /// <param name="propertyNameMapper">Function to map property names. Return <c>null</c> to skip a property.</param> public async Task UpdateSettingsAsync( object settings, IFormCollection form, int storeId, Func <string, string> propertyNameMapper = null) { var settingType = settings.GetType(); var settingName = settingType.Name; var settingProperties = FastProperty.GetProperties(settingType).Values; foreach (var prop in settingProperties) { var name = propertyNameMapper?.Invoke(prop.Name) ?? prop.Name; if (!name.HasValue()) { continue; } var key = string.Concat(settingName, ".", name); if (storeId == 0 || IsOverrideChecked(key, form)) { dynamic value = prop.GetValue(settings); await _settingService.ApplySettingAsync(key, value ?? string.Empty, storeId); } else if (storeId > 0) { await _settingService.RemoveSettingAsync(key, storeId); } } await _db.SaveChangesAsync(); }
private IEnumerable<TreeNode<ModelTreeMember>> BuildModelTreePartForClass(object instance) { var type = instance?.GetType(); if (type == null) { yield break; } foreach (var prop in FastProperty.GetProperties(type).Values) { var pi = prop.Property; if (pi.PropertyType.IsPredefinedType()) { yield return new TreeNode<ModelTreeMember>(new ModelTreeMember { Name = prop.Name, Kind = ModelTreeMemberKind.Primitive }); } else if (typeof(IDictionary<string, object>).IsAssignableFrom(pi.PropertyType)) { yield return BuildModelTreePart(prop.Name, prop.GetValue(instance)); } else if (pi.PropertyType.IsSequenceType()) { yield return new TreeNode<ModelTreeMember>(new ModelTreeMember { Name = prop.Name, Kind = ModelTreeMemberKind.Collection }); } else { var node = new TreeNode<ModelTreeMember>(new ModelTreeMember { Name = prop.Name, Kind = ModelTreeMemberKind.Complex }); node.AppendRange(BuildModelTreePartForClass(prop.GetValue(instance))); yield return node; } } }
/// <summary> /// Updates settings for a store. /// </summary> /// <param name="settings">Settings class instance.</param> /// <param name="form">Form value collection.</param> /// <param name="storeId">Store identifier.</param> /// <param name="settingService">Setting service.</param> /// <param name="propertyNameMapper">Function to map property names. Return <c>null</c> to skip a property.</param> public void UpdateSettings( object settings, FormCollection form, int storeId, ISettingService settingService, Func <string, string> propertyNameMapper = null) { var settingType = settings.GetType(); var settingName = settingType.Name; var settingProperties = FastProperty.GetProperties(settingType).Values; foreach (var prop in settingProperties) { var name = propertyNameMapper?.Invoke(prop.Name) ?? prop.Name; if (string.IsNullOrWhiteSpace(name)) { continue; } var key = string.Concat(settingName, ".", name); if (storeId == 0 || IsOverrideChecked(key, form)) { dynamic value = prop.GetValue(settings); settingService.SetSetting(key, value ?? string.Empty, storeId, false); } else if (storeId > 0) { settingService.DeleteSetting(key, storeId); } } }
private static void MapObject(IDataReader reader, object instance, params string[] fieldsToSkip) { var fastProperties = FastProperty.GetProperties(instance); if (fastProperties.Count == 0) { return; } for (int i = 0; i < reader.FieldCount; i++) { string name = reader.GetName(i); if (fastProperties.ContainsKey(name)) { var fastProp = fastProperties[name]; if (fieldsToSkip.Contains(name)) { continue; } if ((fastProp != null) && fastProp.Property.CanWrite) { var dbValue = reader.GetValue(i); fastProp.SetValue(instance, (dbValue == DBNull.Value) ? null : dbValue); } } } }
protected virtual void SaveSettingCore(ISettings settings, int storeId = 0) { Guard.NotNull(settings, nameof(settings)); using (BeginScope()) { var settingType = settings.GetType(); var prefix = settingType.Name; /* We do not clear cache after each setting update. * This behavior can increase performance because cached settings will not be cleared * and loaded from database after each update */ foreach (var prop in FastProperty.GetProperties(settingType).Values) { // get 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; // Duck typing is not supported in C#. That's why we're using dynamic type dynamic value = prop.GetValue(settings); SetSetting(key, value ?? "", storeId, false); } } }
/// <summary> /// Save settings object /// </summary> /// <typeparam name="T">Type</typeparam> /// <param name="settings">Setting instance</param> /// <param name="storeId">Store identifier</param> public virtual void SaveSetting <T>(T settings, int storeId = 0) where T : ISettings, new() { if (typeof(T).HasAttribute <JsonPersistAttribute>(true)) { SaveSettingsJson <T>(settings); return; } /* We do not clear cache after each setting update. * This behavior can increase performance because cached settings will not be cleared * and loaded from database after each update */ foreach (var prop in FastProperty.GetProperties(typeof(T)).Values) { // get 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 = typeof(T).Name + "." + prop.Name; // Duck typing is not supported in C#. That's why we're using dynamic type dynamic value = prop.GetValue(settings); SetSetting(key, value ?? "", storeId, false); } //and now clear cache ClearCache(); }
protected virtual ISettings LoadSettingCore(Type settingType) { var settings = (ISettings)Activator.CreateInstance(settingType); var prefix = settingType.Name; foreach (var fastProp in FastProperty.GetProperties(settingType).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 = GetSetting <string>(key, 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 { 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) { "Could not convert setting '{0}' to type '{1}'".FormatInvariant(key, prop.PropertyType.Name); } } return(settings); }
public static void Populate(IDictionary <string, object> source, object target, out ICollection <ConvertProblem> problems, params object[] populated) { Guard.NotNull(source, nameof(source)); Guard.NotNull(target, nameof(target)); problems = new List <ConvertProblem>(); if (populated.Any(x => x == target)) { return; } Type t = target.GetType(); if (source != null) { foreach (var fastProp in FastProperty.GetProperties(t).Values) { object value; var pi = fastProp.Property; if (!pi.PropertyType.IsPredefinedSimpleType() && source.TryGetValue(pi.Name, out value) && value is IDictionary <string, object> ) { var nestedValue = fastProp.GetValue(target); ICollection <ConvertProblem> nestedProblems; populated = populated.Concat(new object[] { target }).ToArray(); Populate((IDictionary <string, object>)value, nestedValue, out nestedProblems, populated); if (nestedProblems != null && nestedProblems.Any()) { problems.AddRange(nestedProblems); } WriteToProperty(target, fastProp, nestedValue, problems); } else if (pi.PropertyType.IsArray && !source.ContainsKey(pi.Name)) { WriteToProperty(target, fastProp, RetrieveArrayValues(pi, source, problems), problems); } else { if (source.TryGetValue(pi.Name, out value)) { WriteToProperty(target, fastProp, value, problems); } } } } }
private RenderParameters CreateParameters(object data, IFormatProvider formatProvider) { var p = new RenderParameters(formatProvider); Hash hash = null; if (data is ISafeObject so) { if (so.GetWrappedObject() is IDictionary <string, object> soDict) { hash = Hash.FromDictionary(soDict); } else { data = so.GetWrappedObject(); } } if (hash == null) { hash = new Hash(); if (data is IDictionary <string, object> dict) { foreach (var kvp in dict) { hash[kvp.Key] = LiquidUtil.CreateSafeObject(kvp.Value); } } else { var props = FastProperty.GetProperties(data.GetType()); foreach (var prop in props) { hash[prop.Key] = LiquidUtil.CreateSafeObject(prop.Value.GetValue(data)); } } } p.LocalVariables = hash; p.ErrorsOutputMode = HostingEnvironment.IsHosted ? ErrorsOutputMode.Display : ErrorsOutputMode.Rethrow; return(p); }
internal int DetachInternal(BaseEntity obj, ISet <BaseEntity> objSet, bool deep) { if (obj == null) { return(0); } int numDetached = 0; if (deep) { // This is to prevent an infinite recursion when the child object has a navigation property // that points back to the parent if (objSet != null && !objSet.Add(obj)) { return(0); } // Recursively detach all navigation properties foreach (var prop in FastProperty.GetProperties(obj.GetUnproxiedType()).Values) { if (typeof(BaseEntity).IsAssignableFrom(prop.Property.PropertyType)) { numDetached += DetachInternal(prop.GetValue(obj) as BaseEntity, objSet, deep); } else if (typeof(IEnumerable <BaseEntity>).IsAssignableFrom(prop.Property.PropertyType)) { var val = prop.GetValue(obj); if (val is IEnumerable <BaseEntity> list) { foreach (var item in list.ToList()) { numDetached += DetachInternal(item, objSet, deep); } } } } } base.Entry(obj).State = EfState.Detached; numDetached++; return(numDetached); }
/// <summary> /// Copies common validation rules from <typeparamref name="TEntity"/> type over to corresponding <typeparamref name="TModel"/> type. /// Common rules are: Required and MaxLength rules on string properties (either fluently mapped or annotated). /// </summary> /// <typeparam name="TEntity">The type of source entity.</typeparam> /// <param name="db">The data context instance to which <typeparamref name="TEntity"/> belongs.</param> /// <param name="ignoreProperties">An optional list of property names to ignore.</param> protected virtual void CopyFromEntityRules <TEntity>(DbContext db, params string[] ignoreProperties) where TEntity : BaseEntity, new() { Guard.NotNull(db, nameof(db)); var entityType = db.Model.GetEntityTypes(typeof(TEntity)).FirstOrDefault(); if (entityType != null) { // Get all model properties var modelProps = FastProperty.GetProperties(typeof(TModel), PropertyCachingStrategy.EagerCached); // Get all entity properties not in exclusion list var entityProps = entityType.GetProperties() .Where(x => x.ClrType == typeof(string) && !ignoreProperties.Contains(x.Name)) .OfType <IMutableProperty>(); // Loop thru all entity string properties foreach (var entityProp in entityProps) { // Check if target model contains property (must be of same name and type) if (modelProps.TryGetValue(entityProp.Name, out var modelProp) && modelProp.Property.PropertyType == typeof(string)) { var isNullable = entityProp.IsNullable; var maxLength = entityProp.GetMaxLength(); if (!isNullable || maxLength.HasValue) { var expression = DynamicExpressionParser.ParseLambda <TModel, string>(null, false, "@" + modelProp.Name); if (!isNullable) { RuleFor(expression).NotEmpty(); } if (maxLength.HasValue) { RuleFor(expression).Length(0, maxLength.Value); } } } } } }
// REVIEW: Dieser Code ist redundant mit DefaultModelBinder u.Ä. Entweder ablösen oder eliminieren (vielleicht ist es ja in diesem Kontext notwendig!??!) private static object RetrieveArrayValues(PropertyInfo arrayProp, IDictionary <string, object> source, ICollection <ConvertProblem> problems) { Type elemType = arrayProp.PropertyType.GetElementType(); bool anyValuesFound = true; int idx = 0; var elements = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(elemType)); var properties = FastProperty.GetProperties(elemType); while (anyValuesFound) { object curElement = null; anyValuesFound = false; // false until proven otherwise foreach (var prop in properties.Values) { //var key = string.Format("_{0}{1}_{2}", idx, arrayProp.Name, pd.Name); var key = string.Format("{0}[{1}].{2}", arrayProp.Name, idx, prop.Name); object value; if (source.TryGetValue(key, out value)) { anyValuesFound = true; if (curElement == null) { curElement = Activator.CreateInstance(elemType); elements.Add(curElement); } SetPropFromValue(value, curElement, prop, problems); } } idx++; } var elementArray = Array.CreateInstance(elemType, elements.Count); elements.CopyTo(elementArray, 0); return(elementArray); }
private static T MapReaderToObject <T>(DbDataReader reader) { var fastProps = FastProperty.GetProperties(typeof(T)); var obj = Activator.CreateInstance <T>(); for (int i = 0; i < reader.FieldCount; i++) { if (!reader.IsDBNull(i)) { string columnName = reader.GetName(i); if (fastProps.TryGetValue(columnName, out var prop)) { prop.SetValue(obj, reader.GetValue(i)); } } } return(obj); }
public bool SaveSetting <T>(T settings, int storeId = 0) where T : ISettings, new() { Guard.NotNull(settings, nameof(settings)); using (BeginScope(clearCache: true)) { var hasChanges = false; var modifiedProperties = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); var settingType = typeof(T); var prefix = settingType.Name; /* We do not clear cache after each setting update. * This behavior can increase performance because cached settings will not be cleared * and loaded from database after each update */ foreach (var prop in FastProperty.GetProperties(settingType).Values) { // get 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; // Duck typing is not supported in C#. That's why we're using dynamic type dynamic currentValue = prop.GetValue(settings); if (SetSetting(key, currentValue ?? "", storeId, false) > SaveSettingResult.Unchanged) { hasChanges = true; } } return(hasChanges); } }
public void UpdateSettings(object settings, FormCollection form, int storeId, ISettingService settingService, ILocalizedModelLocal localized = null) { var settingName = settings.GetType().Name; var properties = FastProperty.GetProperties(localized == null ? settings.GetType() : localized.GetType()).Values; foreach (var prop in properties) { var name = prop.Name; var key = settingName + "." + name; if (storeId == 0 || IsOverrideChecked(key, form)) { dynamic value = prop.GetValue(localized == null ? settings : localized); settingService.SetSetting(key, value == null ? "" : value, storeId, false); } else if (storeId > 0) { settingService.DeleteSetting(key, storeId); } } }
/// <summary> /// Updates settings for a store. /// </summary> /// <param name="settings">Settings class instance.</param> /// <param name="form">Form value collection.</param> /// <param name="storeId">Store identifier.</param> /// <param name="settingService">Setting service.</param> /// <param name="localized">Localized model.</param> /// <param name="propertyNameMapper">Function to map property names. Return <c>null</c> to skip a property.</param> public void UpdateSettings( object settings, FormCollection form, int storeId, ISettingService settingService, ILocalizedModelLocal localized = null, Func <string, string> propertyNameMapper = null) { var settingName = settings.GetType().Name; var properties = FastProperty.GetProperties(localized == null ? settings.GetType() : localized.GetType()).Values; foreach (var prop in properties) { var name = prop.Name; if (propertyNameMapper != null) { name = propertyNameMapper(name); } if (string.IsNullOrWhiteSpace(name)) { continue; } var key = string.Concat(settingName, ".", name); if (storeId == 0 || IsOverrideChecked(key, form)) { dynamic value = prop.GetValue(localized == null ? settings : localized); settingService.SetSetting(key, value == null ? "" : value, storeId, false); } else if (storeId > 0) { settingService.DeleteSetting(key, storeId); } } }
/// <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); }
/// 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); }
public virtual async Task <Product> CloneProductAsync( Product product, string cloneName, bool isPublished, bool copyAssociatedProducts = true) { Guard.NotNull(product, nameof(product)); Guard.NotEmpty(cloneName, nameof(cloneName)); var localizedKeySelectors = new List <Expression <Func <Product, string> > > { x => x.Name, x => x.ShortDescription, x => x.FullDescription, x => x.MetaKeywords, x => x.MetaDescription, x => x.MetaTitle, x => x.BundleTitleText }; var clone = new Product(); var utcNow = DateTime.UtcNow; var languages = await _languageService.GetAllLanguagesAsync(true); int?sampleDownloadId = null; // Enable hooks for slugs cache invalidation. using (_chronometer.Step("Clone product " + product.Id)) using (var scope = new DbContextScope(_db, autoDetectChanges: false, hooksEnabled: true, deferCommit: true, forceNoTracking: true)) { if (product.HasSampleDownload && product.SampleDownload != null) { var sampleDownloadClone = product.SampleDownload.Clone(); _db.Downloads.Add(sampleDownloadClone); await scope.CommitAsync(); sampleDownloadId = sampleDownloadClone.Id; } var props = FastProperty.GetProperties(typeof(Product), PropertyCachingStrategy.EagerCached); foreach (var prop in props.Values) { if (prop.IsComplexType) { continue; } if (!prop.IsPublicSettable) { continue; } prop.SetValue(clone, prop.GetValue(product)); } clone.Id = 0; clone.Name = cloneName; clone.SampleDownloadId = sampleDownloadId; clone.Published = isPublished; clone.CreatedOnUtc = utcNow; clone.UpdatedOnUtc = utcNow; // Category mappings. clone.ProductCategories.AddRange(product.ProductCategories.Select(x => new ProductCategory { CategoryId = x.CategoryId, IsFeaturedProduct = x.IsFeaturedProduct, DisplayOrder = x.DisplayOrder })); // Manufacturer mappings. clone.ProductManufacturers.AddRange(product.ProductManufacturers.Select(x => new ProductManufacturer { ManufacturerId = x.ManufacturerId, IsFeaturedProduct = x.IsFeaturedProduct, DisplayOrder = x.DisplayOrder })); // Media file mappings. clone.ProductPictures.AddRange(product.ProductPictures.Select(x => new ProductMediaFile { MediaFileId = x.MediaFileId, DisplayOrder = x.DisplayOrder })); if (clone.MainPictureId == null) { clone.MainPictureId = product.ProductPictures.FirstOrDefault()?.MediaFileId; } // Product specification attributes. clone.ProductSpecificationAttributes.AddRange(product.ProductSpecificationAttributes.Select(x => new ProductSpecificationAttribute { SpecificationAttributeOptionId = x.SpecificationAttributeOptionId, AllowFiltering = x.AllowFiltering, ShowOnProductPage = x.ShowOnProductPage, DisplayOrder = x.DisplayOrder })); // Tier prices. clone.TierPrices.AddRange(product.TierPrices.Select(x => new TierPrice { StoreId = x.StoreId, CustomerRoleId = x.CustomerRoleId, Quantity = x.Quantity, Price = x.Price, CalculationMethod = x.CalculationMethod })); clone.HasTierPrices = clone.TierPrices.Any(); // Discount mappings. foreach (var discount in product.AppliedDiscounts) { clone.AppliedDiscounts.Add(discount); clone.HasDiscountsApplied = true; } // Tags. foreach (var tag in product.ProductTags) { clone.ProductTags.Add(tag); } // >>>>>>> Put clone to db (from here on we need the product clone's ID). _db.Products.Add(clone); await scope.CommitAsync(); // Store mappings. var selectedStoreIds = await _storeMappingService.GetAuthorizedStoreIdsAsync(product); selectedStoreIds.Each(id => _storeMappingService.AddStoreMapping(clone, id)); await ProcessPromotions(product, clone); await ProcessSlugs(product, clone, languages); await ProcessLocalizations(product, clone, localizedKeySelectors, languages); await ProcessDownloads(product, clone); // >>>>>>> Put to db. await scope.CommitAsync(); await ProcessBundleItems(scope, product, clone, languages); // Attributes and attribute combinations. await ProcessAttributes(scope, product, clone, languages); // Update computed properties. clone.LowestAttributeCombinationPrice = await _db.ProductVariantAttributeCombinations .ApplyLowestPriceFilter(clone.Id) .Select(x => x.Price) .FirstOrDefaultAsync(); // Associated products. if (copyAssociatedProducts && product.ProductType != ProductType.BundledProduct) { await ProcessAssociatedProducts(product, clone, isPublished); } // >>>>>>> Our final commit. await scope.CommitAsync(); } return(clone); }
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); }
/// Load settings /// </summary> /// <typeparam name="T">Type</typeparam> /// <param name="storeId">Store identifier for which settigns should be loaded</param> 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>(); 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; // 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; } object value = converter.ConvertFrom(setting); //set property fastProp.SetValue(settings, value); } return(settings); }
protected virtual ISettings LoadSettingCore(Type settingType, int storeId = 0) { if (settingType.HasAttribute <JsonPersistAttribute>(true)) { return(LoadSettingsJson(settingType, storeId)); } var settings = (ISettings)Activator.CreateInstance(settingType); var prefix = settingType.Name; foreach (var fastProp in FastProperty.GetProperties(settingType).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); }
protected virtual ISettings LoadSettingCore(Type settingType, int storeId = 0) { var allSettings = GetAllCachedSettings(); var instance = (ISettings)Activator.CreateInstance(settingType); var prefix = settingType.Name; foreach (var fastProp in FastProperty.GetProperties(settingType).Values) { var prop = fastProp.Property; // Get properties we can read and write to if (!prop.CanWrite) { continue; } string key = prefix + "." + prop.Name; if (!allSettings.TryGetValue(CreateCacheKey(key, storeId), out var cachedSetting) && storeId > 0) { // Fallback to shared (storeId = 0) allSettings.TryGetValue(CreateCacheKey(key, 0), out cachedSetting); } string setting = cachedSetting?.Value; if (setting == null) { if (fastProp.IsSequenceType) { if ((fastProp.GetValue(instance) 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 { 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); }