-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
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:
- Update the Worker template to use
Host.CreateApplicationBuilderaspnetcore#47720 (comment) - tweak that simplifies Worker startup code aspnetcore#43056
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 aBuildmethod. - 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