Beispiel #1
0
        private void Init()
        {
            //use path defined in attribute if specified
            if (Attribute.GetCustomAttribute(_type, typeof(SettingPathAttribute)) is SettingPathAttribute pathAttribute)
            {
                _sectionPath = pathAttribute.Path;
            }
            //use typename if nothing is specified
            else
            {
                _sectionPath = _type.Name;
            }


            //read current values from IConfiguration
            if (string.IsNullOrWhiteSpace(_sectionPath))
            {
                _configRoot.Bind(this);
            }
            else
            {
                _configRoot.GetSection(_sectionPath).Bind(this);
            }



            //ApplyReadTransformations
            foreach (var transformation in _options.StringTransformations)
            {
                StringTransformerBase.TransformObject(this, _configRoot, transformation.PerformReadTransformation);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Save this Configuration.
        /// SettingsSaveDirectory should be defined if no filePath is given.
        /// </summary>
        public string Save()
        {
            //decide for a filePath
            var filePath = _type.GetSavePathForSetting(_options);


            //ApplyWriteTransformations in reverse order
            var transformations = _options.StringTransformations;

            transformations.Reverse();
            foreach (var transformation in transformations)
            {
                StringTransformerBase.TransformObject(this, _configRoot, transformation.PerformWriteTransformation);
            }

            //save the stuff
            var obj = JObject.FromObject(this);

            //use defined path if not root
            if (!string.IsNullOrWhiteSpace(_sectionPath))
            {
                obj = _sectionPath.Split(':')
                      .Reverse()
                      .Aggregate(obj, (current, section) => new JObject {
                    { section, current }
                });
            }

            File.WriteAllText(filePath, obj.ToString());
            return(filePath);
        }
Beispiel #3
0
        /// <summary>
        /// Export this configuration based on root level to a given file path
        /// given folder must already exist
        /// </summary>
        /// <param name="filePath">file path to export to</param>
        public void Save(string filePath)
        {
            var type        = GetType();
            var copyForSave = MemberwiseClone();

            //decide for a SectionPath
            var sectionPath = type.GetSectionPath();

            //ApplyWriteTransformations in reverse order
            var transformations = ConfigurationOptions.StringTransformations.ToList();

            transformations.Reverse();
            foreach (var transformation in transformations)
            {
                StringTransformerBase.TransformObject(copyForSave, ConfigurationRoot, transformation.PerformWriteTransformation);
            }

            //save the stuff
            var obj = JObject.FromObject(copyForSave);

            //use defined path if not root
            if (!string.IsNullOrWhiteSpace(sectionPath))
            {
                obj = sectionPath.Split(':')
                      .Reverse()
                      .Aggregate(obj, (current, section) => new JObject {
                    { section, current }
                });
            }

            File.WriteAllText(filePath, obj.ToString());
        }
Beispiel #4
0
        private void Init()
        {
            //problems:
            //a: if multiple providers provide values for a collection, the values get added
            //doubleMerge: when having Config inside Config, Bind will be executed twice
            //   Bind binds recursive, so the subConfig Constructor calls Init (bind#1) and then binds again below (bind#2)
            //c: On the init call from Change token, existing element will be bound again
            //d: setting classes will be registered as singletons, but when using sub settings is used,
            //   you will end up with separate instances despite registrations. To handle this correctly,
            //   sub settings would need to be resolved from ioc, and set in this instance.


            #region doubleMerge

            //create sub Settings by us here, so they will not get double bound here
            //after binding below, the constructor of the sub class will bind, and then the binding here will bind it again
            //so with merge behaviour of binding, values of array will be doubled
            //https://github.com/dotnet/runtime/issues/46988

            //idea for doubleMerge workaround:
            // construct sub configs before binding (has correct values) and replace here after binding.

            var subSettings = new Dictionary <PropertyInfo, object>();
            foreach (var propertyInfo in GetType().GetProperties()
                     .Where(x => x.CanRead && x.CanWrite)
                     .Where(x => typeof(SettingsBase).IsAssignableFrom(x.PropertyType)))
            {
                var subSetting = Activator.CreateInstance(propertyInfo.PropertyType);
                subSettings.Add(propertyInfo, subSetting);
            }

            #endregion


            var sectionPath = GetType().GetSectionPath();
            //read current values from IConfiguration
            if (string.IsNullOrWhiteSpace(sectionPath))
            {
                ConfigurationRoot.Bind(this);
            }
            else
            {
                ConfigurationRoot.GetSection(sectionPath).Bind(this);
            }

            //ApplyReadTransformations
            foreach (var transformation in ConfigurationOptions.StringTransformations)
            {
                StringTransformerBase.TransformObject(this, ConfigurationRoot, transformation.PerformReadTransformation);
            }

            #region doubleMerge

            //set back sub settings
            foreach (var pair in subSettings)
            {
                pair.Key.SetValue(this, pair.Value);
            }

            #endregion
        }