public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(Path.Combine(Directory.GetCurrentDirectory(), Conf)) .AddJsonFile(AppSettingsJson, optional: true, reloadOnChange: true) .AddEnvironmentVariables(); Configuration = builder.Build(); ConfigurationRoot = builder.Build(); ConfigurationRoot.Bind(AppSettings); }
/// <summary>Attempts to bind the given object instance to configuration section value by FileConfigurationProvider.</summary> /// <param name="options">The object to bind.</param> /// <param name="value">The value to bind.</param> /// <param name="provider">The <see cref="T:FileConfigurationProvider" /> to load the value.</param> public static void Bind <TOptions>([NotNull] TOptions options, string value, [NotNull] FileConfigurationProvider provider) where TOptions : class { if (options == null) { throw new ArgumentNullException(nameof(options)); } if (string.IsNullOrWhiteSpace(value)) { return; } if (provider == null) { throw new ArgumentNullException(nameof(provider)); } var root = new ConfigurationRoot(new List <IConfigurationProvider> { provider }); using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value))) provider.Load(stream); root.Bind(options); }
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 }