dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.19k stars 9.93k forks source link

Allow minimal host to be created without default HostBuilder behavior #32485

Closed davidfowl closed 1 year ago

davidfowl commented 3 years ago

Background and Motivation

The default host builder pulls in a ton of dependencies that are rooted for trimming by default. We should have a mode where the minimal host is dependency minimal as well.

These numbers are native AOT net8.0 compiled on linx-x64:

  1. WebApplication.CreateBuilder() = 18.7 MB
  2. With prototype changes of the proposed API - 12.9 MB

We can stick to the current naming convention and use the existing Create/CreateBuilder methods as the one with the defaults and CreateEmptyBuilder to be the empty one:

Proposed API

namespace Microsoft.AspNetCore.Builder
{
    public class WebApplication
    {
       public static WebApplication Create(string[] args);
       public static WebApplicationBuilder CreateBuilder();
       public static WebApplicationBuilder CreateBuilder(string[] args);
       public static WebApplicationBuilder CreateBuilder(WebApplicationOptions options);
+      public static WebApplicationBuilder CreateEmptyBuilder();
+      public static WebApplicationBuilder CreateEmptyBuilder(string[] args);
+      public static WebApplicationBuilder CreateEmptyBuilder(WebApplicationOptions options);
    }
}

namespace  Microsoft.Extensions.Hosting
{
    public class GenericHostWebHostBuilderExtensions
    {
       public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure)
       public static IHostBuilder ConfigureWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure, Action<WebHostBuilderOptions> configureWebHostBuilder)
+      public static IHostBuilder ConfigureEmptyWebHost(this IHostBuilder builder, Action<IWebHostBuilder> configure, Action<WebHostBuilderOptions> configureWebHostBuilder)
    }
}

API Usage

WebApplicationBuilder builder = WebApplication.CreateEmptyBuilder();
builder.Logging.AddConsole();

WebApplication app = builder.Build();

app.MapGet("/", () => "Hello World");

app.Run();

Features

When creating an "empty" web application, the following features will be on (✅) or off (❌) by default. Note that these features can be enabled by the app explicitly after creating the builder/application. They just won't be enabled by default, in order to reduce app size.

Alternative Designs

We could create whole new class names for another type of "Application" than a "WebApplication". Something like:

var apiBuilder = ApiApplication.CreateBuilder(args);
var apiApp = builder.Builder();

Other possible names include:

Risks

Potential confusion about which one to call. The template should make it obvious that the "empty" builder doesn't have anything in it, and you need to add things like appsettings, console logging, etc.

DamianEdwards commented 1 year ago

Note on IHostingStartup: it's used to enable various inner-loop features (i.e. in VS features during dev time). We might want to think about how we could enable those to still work during inner-loop given the app is still running on CoreCLR there, e.g. ideas:

Similar story for UserSecrets which is only intended for use during inner-loop and is the foundation of other dev-time experiences like dotnet user-jwts.

webczat commented 1 year ago

about routing middleware, isn't it that it's not added unless you call the map family of functions? or maybe it's only not added if you add it manually. Anyway, you also mean you don't add routing services?

davidfowl commented 1 year ago

@webczat

about routing middleware, isn't it that it's not added unless you call the map family of functions? or maybe it's only not added if you add it manually.

Chicken and egg problem. The Map functions are defined on the application and routing needs to be added so that they can be used.

davidfowl commented 1 year ago

@eerhardt It should be possible to turn on these features after the fact.

eerhardt commented 1 year ago

It should be possible to turn on these features after the fact.

I've updated the top proposal's Features section to make this more explicit.

davidfowl commented 1 year ago

@eerhardt I still think we should do CreateEmptyBuilder

DamianEdwards commented 1 year ago

@eerhardt I still think we should do CreateEmptyBuilder

💯

eerhardt commented 1 year ago

Agreed. Especially now that we added stuff back to "SlimBuilder" to make it more convenient. I can open a new issue specifically for it.

eerhardt commented 1 year ago

I opened https://github.com/dotnet/aspnetcore/issues/48811 for CreateEmptyBuilder.