diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostApplicationBuilder.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostApplicationBuilder.cs index c26fdad6b7473..9962638c49d6a 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostApplicationBuilder.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostApplicationBuilder.cs @@ -88,7 +88,12 @@ public HostApplicationBuilder(HostApplicationBuilderSettings? settings) if (!settings.DisableDefaults) { - HostingHostBuilderExtensions.ApplyDefaultHostConfiguration(Configuration, settings.Args); + if (settings.ContentRootPath is null && Configuration[HostDefaults.ContentRootKey] is null) + { + HostingHostBuilderExtensions.SetDefaultContentRoot(Configuration); + } + + HostingHostBuilderExtensions.AddDefaultHostConfigurationSources(Configuration, settings.Args); } // HostApplicationBuilderSettings override all other config sources. diff --git a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs index ad09104a153ce..a22f5bf31ac8b 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs @@ -201,7 +201,13 @@ public static IHostBuilder ConfigureDefaults(this IHostBuilder builder, string[] .UseServiceProviderFactory(context => new DefaultServiceProviderFactory(CreateDefaultServiceProviderOptions(context))); } - internal static void ApplyDefaultHostConfiguration(IConfigurationBuilder hostConfigBuilder, string[]? args) + private static void ApplyDefaultHostConfiguration(IConfigurationBuilder hostConfigBuilder, string[]? args) + { + SetDefaultContentRoot(hostConfigBuilder); + AddDefaultHostConfigurationSources(hostConfigBuilder, args); + } + + internal static void SetDefaultContentRoot(IConfigurationBuilder hostConfigBuilder) { // If we're running anywhere other than C:\Windows\system32, we default to using the CWD for the ContentRoot. // However, since many things like Windows services and MSIX installers have C:\Windows\system32 as there CWD which is not likely @@ -219,7 +225,10 @@ internal static void ApplyDefaultHostConfiguration(IConfigurationBuilder hostCon new KeyValuePair(HostDefaults.ContentRootKey, cwd), }); } + } + internal static void AddDefaultHostConfigurationSources(IConfigurationBuilder hostConfigBuilder, string[]? args) + { hostConfigBuilder.AddEnvironmentVariables(prefix: "DOTNET_"); if (args is { Length: > 0 }) { diff --git a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs index 458bf37eb7d00..d363814623f5d 100644 --- a/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs +++ b/src/libraries/Microsoft.Extensions.Hosting/tests/UnitTests/HostApplicationBuilderTests.cs @@ -229,39 +229,55 @@ public void DisableDefaultIHostEnvironmentValues() Assert.IsAssignableFrom(env.ContentRootFileProvider); } - [Fact] - public void ConfigurationSettingCanInfluenceEnvironment() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void ConfigurationSettingCanInfluenceEnvironment(bool disableDefaults) { + var tempPath = Path.GetTempPath(); + using var config = new ConfigurationManager(); config.AddInMemoryCollection(new KeyValuePair[] { new(HostDefaults.ApplicationKey, "AppA" ), new(HostDefaults.EnvironmentKey, "EnvA" ), + new(HostDefaults.ContentRootKey, tempPath) }); var builder = new HostApplicationBuilder(new HostApplicationBuilderSettings { - DisableDefaults = true, + DisableDefaults = disableDefaults, Configuration = config, }); Assert.Equal("AppA", builder.Configuration[HostDefaults.ApplicationKey]); Assert.Equal("EnvA", builder.Configuration[HostDefaults.EnvironmentKey]); + Assert.Equal(tempPath, builder.Configuration[HostDefaults.ContentRootKey]); Assert.Equal("AppA", builder.Environment.ApplicationName); Assert.Equal("EnvA", builder.Environment.EnvironmentName); + Assert.Equal(tempPath, builder.Environment.ContentRootPath); + var fileProviderFromBuilder = Assert.IsType(builder.Environment.ContentRootFileProvider); + Assert.Equal(tempPath, fileProviderFromBuilder.Root); using IHost host = builder.Build(); var hostEnvironmentFromServices = host.Services.GetRequiredService(); Assert.Equal("AppA", hostEnvironmentFromServices.ApplicationName); Assert.Equal("EnvA", hostEnvironmentFromServices.EnvironmentName); + Assert.Equal(tempPath, hostEnvironmentFromServices.ContentRootPath); + var fileProviderFromServices = Assert.IsType(hostEnvironmentFromServices.ContentRootFileProvider); + Assert.Equal(tempPath, fileProviderFromServices.Root); } - [Fact] - public void DirectSettingsOverrideConfigurationSetting() + [Theory] + [InlineData(true)] + [InlineData(false)] + public void DirectSettingsOverrideConfigurationSetting(bool disableDefaults) { + var tempPath = Path.GetTempPath(); + using var config = new ConfigurationManager(); config.AddInMemoryCollection(new KeyValuePair[] @@ -272,23 +288,31 @@ public void DirectSettingsOverrideConfigurationSetting() var builder = new HostApplicationBuilder(new HostApplicationBuilderSettings { - DisableDefaults = true, + DisableDefaults = disableDefaults, Configuration = config, ApplicationName = "AppB", EnvironmentName = "EnvB", + ContentRootPath = tempPath, }); Assert.Equal("AppB", builder.Configuration[HostDefaults.ApplicationKey]); Assert.Equal("EnvB", builder.Configuration[HostDefaults.EnvironmentKey]); + Assert.Equal(tempPath, builder.Configuration[HostDefaults.ContentRootKey]); Assert.Equal("AppB", builder.Environment.ApplicationName); Assert.Equal("EnvB", builder.Environment.EnvironmentName); + Assert.Equal(tempPath, builder.Environment.ContentRootPath); + var fileProviderFromBuilder = Assert.IsType(builder.Environment.ContentRootFileProvider); + Assert.Equal(tempPath, fileProviderFromBuilder.Root); using IHost host = builder.Build(); var hostEnvironmentFromServices = host.Services.GetRequiredService(); Assert.Equal("AppB", hostEnvironmentFromServices.ApplicationName); Assert.Equal("EnvB", hostEnvironmentFromServices.EnvironmentName); + Assert.Equal(tempPath, hostEnvironmentFromServices.ContentRootPath); + var fileProviderFromServices = Assert.IsType(hostEnvironmentFromServices.ContentRootFileProvider); + Assert.Equal(tempPath, fileProviderFromServices.Root); } [Fact]