Skip to content
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

UseEnvironment overwritten by ConfigureWebHostDefaults #47050

Closed
jgauffin opened this issue Jan 15, 2021 · 8 comments · Fixed by #51629
Closed

UseEnvironment overwritten by ConfigureWebHostDefaults #47050

jgauffin opened this issue Jan 15, 2021 · 8 comments · Fixed by #51629
Assignees
Labels
area-Extensions-Hosting bug help wanted [up-for-grabs] Good issue for external contributors
Milestone

Comments

@jgauffin
Copy link

Describe the bug

UseEnvironment is not picked up in ASP.NET Core 3.1.

I'm using UseEnvironment to toggle between configurations when running in Visual Studio (between on-premise and cloud versions of my service).

It worked great in v2.2, but I've recently migrated to 3.1 and it's not being used anymore.

To Reproduce

  1. Set ASPNETCORE_Environment as an environment variable
  2. Try to override it using UseEnvironment:
Host.CreateDefaultBuilder(args)
    .UseEnvironment(EnvironmentName)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .Build();

From what I understand, it cannot be set later as it won't be picked up in the Startup class then.

Workaround

Currently I'm doing the following instead:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        // This overrides the default configuration
        webBuilder.UseSetting(WebHostDefaults.EnvironmentKey, EnvironmentName);
        webBuilder.UseStartup<Startup>();
    })
    .Build();

imho using the explicit UseEnvironment method should always override the default implementation (ASPNETCORE_Environment) as it's not part of the default configuration, and thus means that the dev really wants to override the default config.

I know that this has been discussed in dotnet/aspnetcore#18499. Just saying "wont fix" leads to hours wasted trying to figure out why it isn't working. At least throw an exception NotSupportedException when the API is used until you can fix or remove it.

@jgauffin jgauffin changed the title UseEnvironment not working in v3.1 UseEnvironment is not working in v3.1 Jan 15, 2021
@Tratcher Tratcher transferred this issue from dotnet/aspnetcore Jan 15, 2021
@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@dotnet-issue-labeler dotnet-issue-labeler bot added the untriaged New issue has not been triaged by the area owner label Jan 15, 2021
@ghost
Copy link

ghost commented Jan 15, 2021

Tagging subscribers to this area: @eerhardt, @maryamariyan
See info in area-owners.md if you want to be subscribed.

Issue Details

Describe the bug

UseEnvironment is not picked up in ASP.NET Core 3.1.

I'm using UseEnvironment to toggle between configurations when running in Visual Studio (between on-premise and cloud versions of my service).

It worked great in v2.2, but I've recently migrated to 3.1 and it's not being used anymore.

To Reproduce

  1. Set ASPNETCORE_Environment as an environment variable
  2. Try to override it using UseEnvironment:
Host.CreateDefaultBuilder(args)
    .UseEnvironment(EnvironmentName)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .Build();

From what I understand, it cannot be set later as it won't be picked up in the Startup class then.

Workaround

Currently I'm doing the following instead:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        // This overrides the default configuration
        webBuilder.UseSetting(WebHostDefaults.EnvironmentKey, EnvironmentName);
        webBuilder.UseStartup<Startup>();
    })
    .Build();

imho using the explicit UseEnvironment method should always override the default implementation (ASPNETCORE_Environment) as it's not part of the default configuration, and thus means that the dev really wants to override the default config.

I know that this has been discussed in dotnet/aspnetcore#18499. Just saying "wont fix" leads to hours wasted trying to figure out why it isn't working. At least throw an exception NotSupportedException when the API is used until you can fix or remove it.

Author: jgauffin
Assignees: -
Labels:

area-Extensions-Hosting, untriaged

Milestone: -

@Tratcher
Copy link
Member

Notes from dotnet/aspnetcore#18499:

  • UseEnvironment works today by adding a config provider, but that makes it too easy for ConfigureWebHostDefaults to overwrite.
  • A real fix would likely require redesigning multiple APIs here to allow setting the environment as a higher level host option, but it's not clear how that would compose with CreateDefaultBuilder.

@Tratcher Tratcher changed the title UseEnvironment is not working in v3.1 UseEnvironment overwritten by ConfigureWebHostDefaults Jan 15, 2021
@maryamariyan maryamariyan removed the untriaged New issue has not been triaged by the area owner label Mar 1, 2021
@maryamariyan maryamariyan added this to the 6.0.0 milestone Mar 1, 2021
@ghost ghost moved this from Untriaged to 6.0.0 in ML, Extensions, Globalization, etc, POD. Mar 1, 2021
@maryamariyan maryamariyan added bug help wanted [up-for-grabs] Good issue for external contributors labels Mar 1, 2021
@IEvangelist
Copy link
Member

Hey, @maryamariyan and @eerhardt - do you mind if I take this one?

@eerhardt
Copy link
Member

Go ahead! Thanks.

@IEvangelist
Copy link
Member

IEvangelist commented Apr 20, 2021

Hi @jgauffin,

I'm thinking that we should update some of the docs around the API usage here, perhaps update the /// comments a bit to make it more clear. If the order of operations is changed, this works - so it's not really a bug. It's kind of like assigning a property, and then re-assigning it to a different value - and then expecting it to be the original value (it's unreasonable to expect the original value) Perhaps the ConfigureWebHostDefaults comments could detail what values it configures more explicitly?

If I'm understanding this correctly, isn't another workaround to simply change the order of the fluent-calls?

Instead of:

Host.CreateDefaultBuilder(args)
    .UseEnvironment(EnvironmentName)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .Build();

Do this:

Host.CreateDefaultBuilder(args)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
    .UseEnvironment(EnvironmentName)
    .Build();

Move the call after the defaults are configured:

Host.CreateDefaultBuilder(args)
-   .UseEnvironment(EnvironmentName)
    .ConfigureWebHostDefaults(webBuilder =>
    {
        webBuilder.UseStartup<Startup>();
    })
+   .UseEnvironment(EnvironmentName)
    .Build();

Placing the UseEnvironment after defaults, that works - right? If you're okay with this, I'd like to resolve this issue by updating some of the /// comments on the APIs in question to make it more obvious about the importance of ordering, sound good?

/cc @davidfowl @eerhardt

@jgauffin
Copy link
Author

It was a while ago that I tried, but think that I tried to move it after and that didn't help.

Either way, please throw exceptions if the configuration API is used in a way that doesn't work.

@IEvangelist
Copy link
Member

IEvangelist commented Apr 21, 2021

Hi @jgauffin - this does work. I have verified it. The order matters, you need to chain the fluent UseEnvironment method after any and all calls that configure defaults. In the example above there were two calls to configure defaults that were chained:

  1. Host.CreateDefaultBuilder(args)
  2. ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())

This is common with ASP.NET Core app, as the template uses the .NET runtime Host.CreateDefaultBuilder(args) and then chains the ASP.NET Core ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()) immediately after. These should exist in this order, and additional calls to Configure* and Use* and whatever should be chained after (not between).

Correctly ordered calls

Console app without ASP.NET Core
image

ASP.NET Core app with Startup
image

Incorrectly ordered calls

ASP.NET Core app with Startup
image

Either way, please throw exceptions if the configuration API is used in a way that doesn't work.

I believe that we do throw in situations where things do not work. This situation is different though, it works as designed. We will work to make this more obvious. Thanks again

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Apr 21, 2021
IEvangelist added a commit to dotnet/aspnetcore that referenced this issue Apr 21, 2021
@ghost ghost closed this as completed in #51629 Apr 21, 2021
ML, Extensions, Globalization, etc, POD. automation moved this from 6.0.0 to Done Apr 21, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Apr 21, 2021
@ghost ghost locked as resolved and limited conversation to collaborators May 21, 2021
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Hosting bug help wanted [up-for-grabs] Good issue for external contributors
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants