Is your feature request related to a problem? Please describe.
When configuring the middleware pipeline on application startup, there are a lot of things that can get built, based on the application configuration at that moment in time. Here is a contrived example, real application middleware pipelines are obviously much more complex:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
if (Configuration["UseHsts"] == "True")
{
app.UseHsts();
}
}
-
Once the RequestDelegate has been built, there is no opportunity to respond to any configuration change and re-build it at runtime. For example, if the configuration value for UseHsts was changed shown above, it would be good for the change in this configuration to cause a new RequestDelegate to be built based on latest configuration.
-
It would be nice imho to be able to use / leverage the options pattern, so one can have an options instance passed in when configuring / building the middleware pipeline. Note in the case above, the mixed access to various sources that impact the way the pipeline is built, like: Configuration["UseHsts"] but also env.IsDevelopment() plus customers might also bind options instances directly to various config sections etc - it would be perhaps easier to reason about more complex pipelines if values influencing the control flow of the pipeline could be consolidated into one TOptions object like this:
public class PipelineOptions
{
public bool UseDeveloperExceptionPage { get; set; }
public bool UseHsts { get; set; }
}
Describe the solution you'd like
Here are a couple of very loose suggestions, for how this feature might look, but I don't want to come across as prescriptive in terms of the API's here..
- I'd like to be able to use a TOptions instance when building the middleware pipeline.
- I'd like for that to happen automatically whenever TOptions changes at runtime.
This means I'd probably need some way of registering this somewhere - perhaps in ConfigureServices:
public void ConfigureServices(IServiceCollection services)
{
// Registers an action that can be used to configure a pipeline that will be called whenever TOptions changes.
services.ConfigureRequestDelegate<PipelineOptions>(Configuration, Configure); // registring this is pointless by itself, something would have to monitor for changes and use this factory etc.
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, PipelineOptions options)
{
// Note: PipelineOptions has been passed in reflecting up to date / current options from which I can build the pipeline.
if (options.UseDeveloperExceptionPage)
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
if (options.UseHsts) // I get to use my options class everywhere important. Much cleaner in large pipelines that use a lot of config.
{
app.UseHsts();
}
}
}
public class PipelineOptions
{
public bool UseDeveloperExceptionPage { get; set; }
public bool UseHsts { get; set; }
}
To make this less verbose, its possible the Hosting layer could add something smart for detecting Configure() methods that should be backed by Options Manager / Monitor (I always forget which one of those is the one!) by detecting a variant of a Configure() method with a signature like this indicating a TOptions type:
/// This method would be called at application startup but also whenever `PipelineOptions` changes.
public void Configure<PipelineOptions>(IApplicationBuilder app, IWebHostEnvironment env, PipelineOptions options)
{
// Note: PipelineOptions has been passed in reflecting up to date / current options from which I can build the pipeline.
if (options.UseDeveloperExceptionPage)
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
if (options.UseHsts) // I get to use my options class everywhere important. Much cleaner in large pipelines that use a lot of config.
{
app.UseHsts();
}
}
}
If that method was detected, then by convention it could configure the TOptions instance (perhaps to some default config section prefix like "PipelineOptions:"?) and then register a factory service to provide RequestDelegate at runtime which would be backed by OptionsMonitor to return current version of RequestDelegate and rebuld it when changes occur.
Additional context
Add any other context or screenshots about the feature request here.
Is your feature request related to a problem? Please describe.
When configuring the middleware pipeline on application startup, there are a lot of things that can get built, based on the application configuration at that moment in time. Here is a contrived example, real application middleware pipelines are obviously much more complex:
Once the
RequestDelegatehas been built, there is no opportunity to respond to any configuration change and re-build it at runtime. For example, if the configuration value forUseHstswas changed shown above, it would be good for the change in this configuration to cause a new RequestDelegate to be built based on latest configuration.It would be nice imho to be able to use / leverage the options pattern, so one can have an options instance passed in when configuring / building the middleware pipeline. Note in the case above, the mixed access to various sources that impact the way the pipeline is built, like:
Configuration["UseHsts"]but alsoenv.IsDevelopment()plus customers might also bind options instances directly to various config sections etc - it would be perhaps easier to reason about more complex pipelines if values influencing the control flow of the pipeline could be consolidated into one TOptions object like this:Describe the solution you'd like
Here are a couple of very loose suggestions, for how this feature might look, but I don't want to come across as prescriptive in terms of the API's here..
This means I'd probably need some way of registering this somewhere - perhaps in
ConfigureServices:To make this less verbose, its possible the Hosting layer could add something smart for detecting Configure() methods that should be backed by Options Manager / Monitor (I always forget which one of those is the one!) by detecting a variant of a Configure() method with a signature like this indicating a TOptions type:
If that method was detected, then by convention it could configure the TOptions instance (perhaps to some default config section prefix like "PipelineOptions:"?) and then register a factory service to provide
RequestDelegateat runtime which would be backed by OptionsMonitor to return current version of RequestDelegate and rebuld it when changes occur.Additional context
Add any other context or screenshots about the feature request here.