Skip to content

[API Proposal]: Host.CreateEmptyApplicationBuilder #81280

@eerhardt

Description

@eerhardt

Background and motivation

In .NET 8, we are enabling ASP.NET Minimal APIs to support NativeAOT. As part of this effort, our goal is to get the template app's publish size to 10 MB. To meet this goal, we need to cut unnecessary dependencies in the application.

Some of the unnecessary dependencies come from the Microsoft.Extensions.Hosting.HostApplicationBuilder API. Specifically, the Microsoft.Extensions.Configuration.Json usage for appsettings.json and optional Logging services (Console, Debug, EventSource, EventLog).

We should create a way to create an "empty" HostApplicationBuilder that doesn't bring any of these optional/unnecessary dependencies into the app's closure. Functionally, this would behave the same as new HostApplicationBuilder(new HostApplicationBuilderSettings() { DisableDefaults = true }).

This should cut about 1.3 MB of a NativeAOT published Windows x64 app. Prototyping this change on my machine results the Benchmark app:

Before
15.2 MB (16,007,168 bytes)

After
13.9 MB (14,593,024 bytes)

And 1.4MB on Linux x64:

Before
18.6 MB (19,601,424 bytes)

After
17.2 MB (18,132,768 bytes)

The bulk of this size savings (~1MB) is due to the Console Logger getting trimmed from the app. A follow up issue will be logged to make Console Logging smaller when used/needed.

API Proposal

namespace Microsoft.Extensions.Hosting;

public static class Host
{
        public static HostApplicationBuilder CreateApplicationBuilder();
        public static HostApplicationBuilder CreateApplicationBuilder(string[]? args);
+       public static HostApplicationBuilder CreateEmptyApplicationBuilder(HostApplicationBuilderSettings? settings);
        public static IHostBuilder CreateDefaultBuilder();
        public static IHostBuilder CreateDefaultBuilder(string[]? args);
}
public sealed partial class HostApplicationBuilder
{
    public HostApplicationBuilder() { }
    public HostApplicationBuilder(HostApplicationBuilderSettings? settings) { }
    public HostApplicationBuilder(string[]? args) { }
}

API Usage

var builder = Host.CreateEmptyApplicationBuilder(new HostApplicationBuilderSettings
{
    Args = args,
    ApplicationName = "My App",
    EnvironmentName = "Production",
    ContentRootPath = Environment.CurrentDirectory
    Configuration = new ConfigurationManager(),
});

// do the same things with `builder` as normal
builder.Logging.AddConsole();
builder.Services.AddScoped(_ => new SqliteConnection(connectionString));

IHost host = builder.Build();
host.Run();

Alternative Designs

Create a whole new, duplicate HostApplicationBuilder class that doesn't have these dependencies.

Risks

Users expecting the default behavior of new HostApplicationBuilder() being the same as Host.CreateEmptyApplicationBuilder(new HostApplicationBuilderSettings()).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions