-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Background and Motivation
When developing a new minimal host for ASP.NET Core (WebApplication, WebApplicationBuilder), we found that it would be useful to be able to read from configuration (e.g. appsettings.json and DOTNET_/ASPNETCORE_ environment variables) while still being able to add new configuration sources. Every time a source is added via the IConfigurationBuilder interface, the IConfiguration updates automatically and immediately.
For this reason, we've temporarily introduced a Configuration type to Microsoft.AspNetCore.Builder that does exactly this. This type belongs in Microsoft.Extensions.Configuration though.
Moving this type will be a breaking change in ASP.NET Core between preview6 and preview7, but we're okay this.
Proposed API
namespace Microsoft.Extensions.Configuration
{
+ public sealed class ConfigurationManager : IConfigurationRoot, IConfigurationBuilder, IDisposable
+ {
+ public ConfigurationManager();
+ public string? this[string key] { get; set; }
+ public IConfigurationSection GetSection(string key);
+ public void Dispose();
+ }The members that are required to implement IConfigurationBuilder will be implemented explicitly, so members like IList<IConfigurationSource> IConfigurationBuilder.Sources don't pollute intellisense. Extension methods are generally used to add configuration sources.
Usage Examples
WebApplicationBuilder essentially already exposes this type as a public property. The problem it is trying to solve is being able to read config from appsettings.json and DOTNET_/ASPNETCORE_ while configuring the host's IServiceCollection while at the same time being able to add new configuration sources or even change the content root without having to introduce additional build stages.
using var config = new Config();
config.AddEnvironmentVariables(prefix: "MyCustomPrefix_");
if (config["FileConfig"] == "enabled")
{
config.AddJsonFile("MyConfig.json", optional: true, reloadOnChange: true);
}
string myValueFromJson = config["JsonConfigValue"];
// ...We have docs where we demonstrate manually building an IConfigurationBuilder, reading from the built IConfiguration, and then throwing that away to add a new config source. This is an alternative to that.
Alternative Designs
Update ConfigurationBuilder to implement IConfigurationRoot and basically become this type. It would leave the IConfigurationBuilder methods as normal methods instead of explicit interface implementations like in the proposal.
In the current implementation of Configuration in Microsoft.AspNetCore.Builder, the ChangeBasePath and ChangeFileProvider methods are internal. Consumers of WebApplicationBuilder should generally call builder.WebHost.SetContentRoot() instead. That, in turn, calls these currently-internal methods.
I was thinking an alternative might be an interface or an abstract base class we implement in ASP.NET Core. Perhaps IUpdateConfiguration: IConfigurationRoot, IConfigurationBuilder. I imagine we'd want at least one default implementation in Microsoft.Extensions.Configuration though.
All sources are now reloaded when the IConfigurationBuilder.Properties["FileProvider"] changes.
Risks
It might be confusing to developers if and when this should be used over a plain old ConfigurationBuilder. It also might not be clear if you should call ChangeBasePath or ChangeFileProvider methods instead of the SetBasePath and SetFileProvider methods extension with this new type. The answer is you should.
@maryamariyan @eerhardt @safern @tarekgh @pranavkm @davidfowl @Tratcher