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