Skip to content

Commit

Permalink
Add ConfigureHostOptions extension method on IHostBuilder (#51410)
Browse files Browse the repository at this point in the history
- Add two `ConfigureHostOptions` extension methods
  - Two overloads exist, per [Maryam's comment](https://github.com/dotnet/runtime/pull/49502/files#r596466330)
- Add corresponding unit tests to ensure these new methods function correctly 

Fixes #48743
  • Loading branch information
IEvangelist committed Apr 19, 2021
1 parent 5a4d604 commit 4ab71ae
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public static partial class HostingHostBuilderExtensions
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureAppConfiguration(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.Configuration.IConfigurationBuilder> configureDelegate) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureContainer<TContainerBuilder>(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<TContainerBuilder> configureDelegate) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureDefaults(this Microsoft.Extensions.Hosting.IHostBuilder builder, string[] args) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureHostOptions(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.Hosting.HostBuilderContext, Microsoft.Extensions.Hosting.HostOptions> configureOptions) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureHostOptions(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.Hosting.HostOptions> configureOptions) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureLogging(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.Hosting.HostBuilderContext, Microsoft.Extensions.Logging.ILoggingBuilder> configureLogging) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureLogging(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.Logging.ILoggingBuilder> configureLogging) { throw null; }
public static Microsoft.Extensions.Hosting.IHostBuilder ConfigureServices(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder, System.Action<Microsoft.Extensions.DependencyInjection.IServiceCollection> configureDelegate) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,31 @@ public static IHostBuilder ConfigureLogging(this IHostBuilder hostBuilder, Actio
{
return hostBuilder.ConfigureServices((context, collection) => collection.AddLogging(builder => configureLogging(builder)));
}

/// <summary>
/// Adds a delegate for configuring the <see cref="HostOptions"/> of the <see cref="IHost"/>.
/// </summary>
/// <param name="hostBuilder">The <see cref="IHostBuilder" /> to configure.</param>
/// <param name="configureOptions">The delegate for configuring the <see cref="HostOptions"/>.</param>
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
public static IHostBuilder ConfigureHostOptions(this IHostBuilder hostBuilder, Action<HostBuilderContext, HostOptions> configureOptions)
{
return hostBuilder.ConfigureServices(
(context, collection) => collection.Configure<HostOptions>(options => configureOptions(context, options)));
}

/// <summary>
/// Adds a delegate for configuring the <see cref="HostOptions"/> of the <see cref="IHost"/> instance
/// related to th.
/// </summary>
/// <param name="hostBuilder">The <see cref="IHostBuilder" /> to configure.</param>
/// <param name="configureOptions">The delegate for configuring the <see cref="HostOptions"/>.</param>
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
public static IHostBuilder ConfigureHostOptions(this IHostBuilder hostBuilder, Action<HostOptions> configureOptions)
{
return hostBuilder.ConfigureServices(collection => collection.Configure(configureOptions));
}

/// <summary>
/// Sets up the configuration for the remainder of the build process and application. This can be called multiple times and
/// the results will be additive. The results will be available at <see cref="HostBuilderContext.Configuration"/> for
Expand Down Expand Up @@ -245,7 +270,7 @@ public static IHostBuilder ConfigureDefaults(this IHostBuilder builder, string[]
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
public static IHostBuilder UseConsoleLifetime(this IHostBuilder hostBuilder)
{
return hostBuilder.ConfigureServices((context, collection) => collection.AddSingleton<IHostLifetime, ConsoleLifetime>());
return hostBuilder.ConfigureServices(collection => collection.AddSingleton<IHostLifetime, ConsoleLifetime>());
}

/// <summary>
Expand All @@ -257,7 +282,7 @@ public static IHostBuilder UseConsoleLifetime(this IHostBuilder hostBuilder)
/// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>
public static IHostBuilder UseConsoleLifetime(this IHostBuilder hostBuilder, Action<ConsoleLifetimeOptions> configureOptions)
{
return hostBuilder.ConfigureServices((context, collection) =>
return hostBuilder.ConfigureServices(collection =>
{
collection.AddSingleton<IHostLifetime, ConsoleLifetime>();
collection.Configure(configureOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ public void HostConfigParametersReadCorrectly()
{
var parameters = new Dictionary<string, string>()
{
{ "applicationName", "MyProjectReference"},
{ "environment", Environments.Development},
{ "applicationName", "MyProjectReference" },
{ "environment", Environments.Development },
{ "contentRoot", Path.GetFullPath(".") }
};

Expand Down Expand Up @@ -332,6 +332,66 @@ public void DefaultCreatesLoggerFactory()
}
}

public static IEnumerable<object[]> ConfigureHostOptionsTestInput = new[]
{
new object[] { BackgroundServiceExceptionBehavior.Ignore, TimeSpan.FromDays(3) },
new object[] { BackgroundServiceExceptionBehavior.StopHost, TimeSpan.FromTicks(long.MaxValue) },
};

[Theory]
[MemberData(nameof(ConfigureHostOptionsTestInput))]
public void CanConfigureHostOptionsWithOptionsOverload(
BackgroundServiceExceptionBehavior testBehavior, TimeSpan testShutdown)
{
using var host = new HostBuilder()
.ConfigureDefaults(Array.Empty<string>())
.ConfigureHostOptions(
options =>
{
options.BackgroundServiceExceptionBehavior = testBehavior;
options.ShutdownTimeout = testShutdown;
})
.Build();

var options = host.Services.GetRequiredService<IOptions<HostOptions>>();
Assert.NotNull(options.Value);

var hostOptions = options.Value;
Assert.Equal(testBehavior, hostOptions.BackgroundServiceExceptionBehavior);
Assert.Equal(testShutdown, hostOptions.ShutdownTimeout);
}

[Theory]
[MemberData(nameof(ConfigureHostOptionsTestInput))]
public void CanConfigureHostOptionsWithContenxtAndOptionsOverload(
BackgroundServiceExceptionBehavior testBehavior, TimeSpan testShutdown)
{
using var host = new HostBuilder()
.ConfigureDefaults(Array.Empty<string>())
.ConfigureHostOptions(
(context, options) =>
{
context.HostingEnvironment.ApplicationName = "TestApp";
context.HostingEnvironment.EnvironmentName = Environments.Staging;
options.BackgroundServiceExceptionBehavior = testBehavior;
options.ShutdownTimeout = testShutdown;
})
.Build();

var options = host.Services.GetRequiredService<IOptions<HostOptions>>();
Assert.NotNull(options.Value);

var hostOptions = options.Value;
Assert.Equal(testBehavior, hostOptions.BackgroundServiceExceptionBehavior);
Assert.Equal(testShutdown, hostOptions.ShutdownTimeout);

var env = host.Services.GetRequiredService<IHostEnvironment>();

Assert.Equal("TestApp", env.ApplicationName);
Assert.Equal(Environments.Staging, env.EnvironmentName);
}

[Fact]
public void MultipleConfigureLoggingInvokedInOrder()
{
Expand Down Expand Up @@ -552,7 +612,7 @@ public void HostServicesSameServiceProviderAsInHostBuilder()
{
var hostBuilder = Host.CreateDefaultBuilder();
var host = hostBuilder.Build();

var type = hostBuilder.GetType();
var field = type.GetField("_appServices", BindingFlags.Instance | BindingFlags.NonPublic)!;
var appServicesFromHostBuilder = (IServiceProvider)field.GetValue(hostBuilder)!;
Expand Down

0 comments on commit 4ab71ae

Please sign in to comment.