Skip to content

Allow Use of IConfigureOptions Consistently Everywhere #39251

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

Closed
Tracked by #1413
RehanSaeed opened this issue Dec 31, 2021 · 9 comments
Closed
Tracked by #1413

Allow Use of IConfigureOptions Consistently Everywhere #39251

RehanSaeed opened this issue Dec 31, 2021 · 9 comments
Assignees
Labels
✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. investigate old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Status: Resolved

Comments

@RehanSaeed
Copy link
Contributor

RehanSaeed commented Dec 31, 2021

Is your feature request related to a problem? Please describe.

IConfigureOptions<T> allows you to move your configuration code to a separate class. However, it cannot be used with certain API's which require us to pass an Action<T>:

IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services, Action<RedisCacheOptions> setupAction)
IServiceCollection AddHsts(this IServiceCollection services, Action<HstsOptions> configureOptions)

This is not an exhaustive list, there may be others.

Describe the solution you'd like

All API's in ASP.NET Core should be consistent and allow us to configure them using IConfigureOptions<T>. The following overloads should be added:

IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services)
IServiceCollection AddHsts(this IServiceCollection services)
@davidfowl
Copy link
Member

They compose, so it can be used. Are you saying you want overloads that don’t require the action overload?

@RehanSaeed
Copy link
Contributor Author

RehanSaeed commented Dec 31, 2021

Yes, at the moment it's pretty strange to be forced to pass an empty delegate:

services.AddStackExchangeRedisCache(x => {});
services.AddHsts(x => {});

It would be a good idea to review all such API's to see if there are others I missed.

@mkArtakMSFT mkArtakMSFT added the old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels label Jan 3, 2022
@rafikiassumani-msft rafikiassumani-msft added this to the .NET 7 Planning milestone Jan 4, 2022
@ghost
Copy link

ghost commented Jan 4, 2022

Thanks for contacting us.
We're moving this issue to the .NET 7 Planning milestone for future evaluation / consideration. Because it's not immediately obvious that this is a bug in our framework, we would like to keep this around to collect more feedback, which can later help us determine the impact of it. We will re-evaluate this issue, during our next planning meeting(s).
If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues.
To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@BrennanConroy
Copy link
Member

Today we have two common patterns for configuring options when adding built-in ASP.NET Core features.

  1. Single method that takes an Action<OptionType>? and defaults to null
    public static IServerSideBlazorBuilder AddServerSideBlazor(this IServiceCollection services, Action<CircuitOptions>? configure = null)
  2. Two methods, one without Action<OptionType> and the second with Action<OptionType>
    public static IServiceCollection AddAuthorizationCore(this IServiceCollection services)

    public static IServiceCollection AddAuthorizationCore(this IServiceCollection services, Action<AuthorizationOptions> configure)

We should decide on the preferred approach and update any areas that are currently forcing an Action<OptionType> when they don't need to be.
Example, AddCookiePolicy is fine forcing the Action<CookiePolicyOptions> because that's the whole point of the API

public static IServiceCollection AddCookiePolicy(this IServiceCollection services, Action<CookiePolicyOptions> configureOptions)

Bringing this up with API review so we can agree on the pattern we want to use before updating places like AddStackExchangeRedisCache.

@BrennanConroy BrennanConroy added the api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews label Feb 11, 2022
@ghost
Copy link

ghost commented Feb 11, 2022

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@pranavkm
Copy link
Contributor

pranavkm commented Feb 14, 2022

API review:

  • Don't change existing overloads.
  • For existing APIs that are missing the overload that does not accept an options callback, we should add one. For e.g we should do this:
+ IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services)
IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services, Action<RedisCacheOptions> setupAction)
  • For new ones, we think standardize on using the pattern of having two overloads. This should allow for new options to be introduced in a future release without deviating from the pattern and also conforms to existing patterns in the framework.
public static IServerSideBlazorBuilder AddMyFeature(this IServiceCollection services);
public static IServerSideBlazorBuilder AddMyFeature(this IServiceCollection services, Action<MyFeatureOption> configureOptions) ;

configureOptions in the above example can be allowed to be soft-allow null values (i.e. not perform null checks) for the sake of brevity of implementation.

  • In the event we only need the options type to configured without adding any other services, we should standardize on Configure??? as the name for the method e.g. ConfigureMyFeatureOptions(Action<MyFeatureOptions> configureOptions) where configureOptions is non-null.

Separately we'll approve the changes proposed in this issue:

+ IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services)
+ IServiceCollection AddHsts(this IServiceCollection services)

@pranavkm pranavkm added api-approved API was approved in API review, it can be implemented and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels Feb 14, 2022
@halter73
Copy link
Member

halter73 commented May 5, 2022

We decided on the PR (#40689) that the add AddHsts() overload without a callback effectively does nothing. [1] Now the new AddStackExchangeRedisCache overload has even been called into question. Not because it does nothing, but because redis cannot work without configuring custom options.

Options can be configured separately without the callback, but this is uncommon. We're worried that introducing this overload will create confusion only to save seven characters of code in the uncommon case.

+ IServiceCollection AddStackExchangeRedisCache(this IServiceCollection services)

[1]: This brings up questions about whether UseHsts should have taken the options directly similar to UseStaticFiles and let people call .Configure<HstsOptions>( on the service collection themselves if they are so inclined, but I digress.

@halter73 halter73 added api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews and removed api-approved API was approved in API review, it can be implemented labels May 5, 2022
@ghost
Copy link

ghost commented May 5, 2022

Thank you for submitting this for API review. This will be reviewed by @dotnet/aspnet-api-review at the next meeting of the ASP.NET Core API Review group. Please ensure you take a look at the API review process documentation and ensure that:

  • The PR contains changes to the reference-assembly that describe the API change. Or, you have included a snippet of reference-assembly-style code that illustrates the API change.
  • The PR describes the impact to users, both positive (useful new APIs) and negative (breaking changes).
  • Someone is assigned to "champion" this change in the meeting, and they understand the impact and design of the change.

@halter73
Copy link
Member

API Review Notes:

Options can be configured separately without the callback, but this is uncommon. We're worried that introducing this overload will create confusion only to save seven characters of code in the uncommon case.

We are worried that adding the non-options-configuring AddStackExchangeRedisCache(this IServiceCollection services) will create too much confusion by making people think configuring options isn't necessary. If options are configured seperately, calling AddStackExchangeRedisCache(this IServiceCollection services, Action<RedisCacheOptions> configure) with _ => { } is easy enough.

@halter73 halter73 added ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. and removed api-ready-for-review API is ready for formal API review - https://github.com/dotnet/apireviews labels May 16, 2022
@ghost ghost added the Status: Resolved label May 16, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jun 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. investigate old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Status: Resolved
Projects
None yet
Development

No branches or pull requests

7 participants