Aspnetcore: Startup class activation allow additional params

Created on 12 Mar 2020  路  5Comments  路  Source: dotnet/aspnetcore

Startup classes cannot be activated with additional constructor params

When using a startup class, suppose I want my constructor to have some arbitrary additional parameters- like an ILogger, or an IOptions object. At the moment this is not allowed because the host builder doesnt know how to satisfy those additional constructor parameters when it activates the startup class. However in other situations such as UseMiddleware you can supply those additional parameter values to be used when activating the class, at the point of registering it. You cant do that currently when registering a Startup class. This means if in startup.cs you want to use something like an ILogger that you created in program.cs, you have to resort to accessing it in a static field like Program.Logger etc.

Describe the solution you'd like

The equivalent of
.UseStartup<Startup>(logger, foo, bar)

When the startup class is activated, any constructor parameters that the host doesn't natively know how to resolve, will be matched from the additional object instances supplied at the point of registering the startup class. This is a pattern found elsewhere in certain places in the framework.

Additional context

Add any other context or screenshots about the feature request here.

area-hosting enhancement

Most helpful comment

API proposal:

```C#
public class WebHostBuilderExtensions
{
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Func startupFactory);
}

## Usage

```C#
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder()
            .ConfigureWebHost(builder =>
            {
                builder.UseStartup(context => new Startup());
            })
            .Build();

        await host.RunAsync();
    }
}

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

Notes

  • Gives the user control over creation of the startup class with the WebHostBuilderContext.
  • We still invoke everything via reflection, there's no startup interface here. This makes the change small and reduces the risk since the only change is how the instance is resolved.

cc @Tratcher

All 5 comments

This makes sense to me. I鈥檒l play with it and see if there are any rough edges

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

API proposal:

```C#
public class WebHostBuilderExtensions
{
public static IWebHostBuilder UseStartup(this IWebHostBuilder hostBuilder, Func startupFactory);
}

## Usage

```C#
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;

public class Program
{
    public static async Task Main(string[] args)
    {
        var host = Host.CreateDefaultBuilder()
            .ConfigureWebHost(builder =>
            {
                builder.UseStartup(context => new Startup());
            })
            .Build();

        await host.RunAsync();
    }
}

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
}

Notes

  • Gives the user control over creation of the startup class with the WebHostBuilderContext.
  • We still invoke everything via reflection, there's no startup interface here. This makes the change small and reduces the risk since the only change is how the instance is resolved.

cc @Tratcher

This was merged into the rc1 milestone

Thank you very much!

Was this page helpful?
0 / 5 - 0 ratings