-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Host.CreateEmptyApplicationBuilder #81280
Comments
Tagging subscribers to this area: @dotnet/area-extensions-hosting Issue DetailsBackground and motivationIn .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 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 In prototyping this API, it saves roughly 300 KB in the published Linux x64 app. API Proposalnamespace 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 Usagevar 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 DesignsCreate a whole new, duplicate HostApplicationBuilder class that doesn't have these dependencies. RisksUsers expecting the default behavior of
|
Is |
"Hosting" implies that there is DI. It is intrinsic to what the Hosting layer provides. A HostApplicationBuilder builds an runtime/src/libraries/Microsoft.Extensions.Hosting.Abstractions/src/IHost.cs Lines 13 to 34 in a342915
"Empty" means there are no registered services. i.e. there are no Logging or Configuration providers (or other "optional" services). |
Gotcha, that makes total sense. |
Through a lot of adding and removing things during the discussion, we added an overload of CreateApplicationBuilder that takes the settings object for symmetry and a clear path from the existing pattern to the new one. This new overload is a source-breaking change for the namespace Microsoft.Extensions.Hosting;
public static class Host
{
public static HostApplicationBuilder CreateApplicationBuilder();
+ public static HostApplicationBuilder CreateApplicationBuilder(HostApplicationBuilderSettings? settings);
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) { }
} |
I didn't realize the HostApplicationBuilder has a public constructor, how is that different from empty? |
HostApplicationBuilder's ctor is identical to CreateApplicationBuilder(), which just calls the ctor, and that constructor does much more than nothing: runtime/src/libraries/Microsoft.Extensions.Hosting/src/Host.cs Lines 59 to 76 in 1c442fc
I pushed on whether we could just taking a breaking change to HostApplicationBuilder's ctors to make them "empty", but was assured that'd be bad :) |
Seems cleaner to have constructors do nothing. I guess it would be bad if you updated hosting on an older version of ASP.NET Core. This API isn't widely used enough yet to be concerned about other scenarios IMHO. |
I agree that there are very few consumers of this API other than ASP.NET Core. Using grep.app, I only found one third-party app creating a We could theoretically patch |
If we really don't like the existing
I think the plan we approved yesterday is good enough to meet our goals. But if we wanted to make the current APIs better, I would lean towards option 2, and just move away from the constructors all together. This would be consistent with ASP.NET's WebApplicationBuilder, which doesn't expose constructors, but instead uses a static factory method: |
Introduce a way to create an "empty" HostApplicationBuilder that doesn't bring any optional/unnecessary dependencies into the app's closure. This has the same functional behavior as DisableDefaults=true while allowing for the unused code to be trimmed. Also add CreateApplicationBuilder(HostApplicationBuilderSettings settings) overload to make the Host factory methods complete. Fix dotnet#81280
* Add Host.CreateEmptyApplicationBuilder Introduce a way to create an "empty" HostApplicationBuilder that doesn't bring any optional/unnecessary dependencies into the app's closure. This has the same functional behavior as DisableDefaults=true while allowing for the unused code to be trimmed. Also add CreateApplicationBuilder(HostApplicationBuilderSettings settings) overload to make the Host factory methods complete. Fix #81280
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 forappsettings.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
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 asHost.CreateEmptyApplicationBuilder(new HostApplicationBuilderSettings())
.The text was updated successfully, but these errors were encountered: