Skip to content

[API Proposal]: Add IHostApplicationBuilder interface #85486

@eerhardt

Description

@eerhardt

Background and motivation

In .NET 6, ASP.NET added a WebApplicationBuilder "minimal hosting" API. This was a new, non-callback approach to the HostBuilder Generic Host API. In .NET 7, Extensions.Hosting added a similar "generic host" API that followed the same non-callback API design.

The problem is these two hosting APIs have the same members (mostly), but don't have a common base abstraction that libraries can add extension methods to. In the previous, callback API IHostBuilder was the interface libraries could extend and add their library-specific DI services, etc. to.

To enable this, we should add a general abstraction to these hosting builder APIs.

See the conversations at:

API Proposal

namespace Microsoft.Extensions.Hosting;

public interface IHostApplicationBuilder
{
    IDictionary<object, object> Properties { get; }

    IConfigurationManager Configuration { get; }
    IHostEnvironment Environment { get; }
    ILoggingBuilder Logging { get; }
    IServiceCollection Services { get; }

    IHost Build();  // See Note below on `Build()`
    void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder>factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder: notnull;
}

-public sealed class HostApplicationBuilder {}
+public sealed class HostApplicationBuilder : IHostApplicationBuilder {}

namespace Microsoft.Extensions.Configuration;

public interface IConfigurationManager : IConfiguration, IConfigurationBuilder
{
}

-public sealed class ConfigurationManager : IConfigurationBuilder, IConfigurationRoot, IDisposable {}
+public sealed class ConfigurationManager : IConfigurationBuilder, IConfigurationRoot, IDisposable, IConfigurationManager {}

Note on Build()

If we wanted to make this API work for all ApplicationBuilders like MauiAppBuilder and WebAssemblyHostBuilder, we would need to think about IHost Build(). Those 2 app models follow this same ApplicationBuilder pattern, but the things they build don't implement IHost. Options here are:

  • Don't put Build() in the interface. But the name of the interface is "Builder", so it doesn't feel right to not have a Build method.
  • For the app models that don't support IHost, they would throw NotSupported for this method. This is my recommendation.

API Usage

Using an existing extension method on IHostBuilder as an example, a new extension method could be written like:

public static class HostBuilderExtensions
{
    public static IHostBuilder AddSteeltoe(this IHostApplicationBuilder hostBuilder, IEnumerable<string> exclusions = null, ILoggerFactory loggerFactory = null)
    {
...
        hostBuilder.Properties[LoggerName] = logger;

        hostBuilder.Configuration.AddSteeltoeConfigServer();
        hostBuilder.Services.AddMongoClient()
    }
}

Alternative Designs

We could make WebApplicationBuilder and HostApplicationBuilder explicitly implement IHostBuilder, but this breaks the API design of making the hosting code minimal, and running inline. It would cause a lot of confusion on when services, config, etc gets added in which order. For this reason, we don't want to keep using the IHostBuilder interface in new code.

Risks

N/A

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions