CommandLineUtils icon indicating copy to clipboard operation
CommandLineUtils copied to clipboard

Environment for generic host integration

Open poke opened this issue 4 years ago • 8 comments

When using the generic host integration, I would like the command line parser to be able to set the the host’s environment (IHostEnvironment.EnvironmentName). This can be done statically like this:

static Task<int> Main(string[] args)
    => new HostBuilder()
        .UseEnvironment("Development")
        .RunCommandLineApplicationAsync<Program>(args);

The default builder is already configured to take this from the --environment command line option. So you can run normal applications using foo.exe --environment Development to set the environment. I would like to keep this option working in order to switch the active application configuration, just like the default host builder does by default.

Right now, I’m doing this to allow setting the environment:

.ConfigureHostConfiguration(config =>
{
    var configApp = new CommandLineApplication();
    configApp.UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.CollectAndContinue;
    var envOption = configApp.Option("--environment", null, CommandOptionType.SingleValue);
    configApp.Execute(args);

    var environment = envOption.Value();
    if (!string.IsNullOrEmpty(environment))
    {
        config.AddInMemoryCollection(new Dictionary<string, string>
        {
            [HostDefaults.EnvironmentKey] = environment,
        });
    }
})

In addition, I also configure the same --environment parameter for the actual program to avoid that throwing later.

Ideally, I would like the RunCommandLineApplicationAsync take care of this automatically. Since it operates on the host builder, it could configure a host configurator as well. There just would be some need to maybe extract the argument parsing so that this doesn’t need to instantiate a full temporary app here the way I do.

poke avatar Mar 25 '20 16:03 poke

This request sounds reasonable. I think the current form of generic host integration can be adjusted to accommodate this, though I'm not completely sure how. @wasabii made a similar request last week to be able to configure logging (see #354). I think there may be a common approach that could help address both requests.

Marking as help-wanted as I don't have time to implement something myself, but I'm open to a pull request to address this.

natemcmaster avatar Mar 27 '20 15:03 natemcmaster

Cool! I’m actually interested to attempt this myself, so I’ll see if I can come up with something good. I would then also try to think about how we could integrate logging as well. I also think it’s fundamentally a very similar problem.

Since I don’t know this codebase that well yet, do you have a pointer what I could use to make the argument parsing work without creating a separate command line application? Is that even possible? Ideally, I would like to “elevate” some arguments out of the app into the host that would impact the host but then be stripped out for the real app (so that you also wouldn’t need to redefine the same arguments). Or maybe have some mechanism to register “host options” that would impact the host instead of the app.

Speaking of, is there a reason that the current integration was built on top of a custom host lifetime and not, for example, a hosted service? I think there would be a bit more flexibility if it was a hosted service—or a similar construct that operated on the host instead of the host builder.

poke avatar Mar 27 '20 15:03 poke

do you have a pointer what I could use to make the argument parsing work without creating a separate command line application? Is that even possible?

Yes and no. It's not really supported. In an ideal world where I have loads of free time, I would have liked to split the parsing code from the code that contains the application lifecycle. In the real world, I've never found the time.

That said, you might be able to get this partially working with workarounds. You should be able to re-use instances of CommandLineApplication. If you call the .Parse method multiple times without it calling any "OnExecute" handlers. The think I think might trip it up (not sure, whould need to test) is usages of CommandLineApplication<TModel>. Parsing may initialize the TModel...which might defeat the whole purpose of the Parse only method...but I attempted to make this initialization as lazy as possible in #332.

Speaking of, is there a reason that the current integration was built on top of a custom host lifetime and not, for example, a hosted service?

I'm not sure. The hosting integration was almost entirely built by others. I have reviewed the code to make sure it wasn't obviously flawed and made of a few minor fixes, but otherwise, I haven't spent much time on it myself.

natemcmaster avatar Mar 29 '20 21:03 natemcmaster

Alright, thanks, that does help and gives me something to look at. I’ll see if I can make anything useful out of that.

poke avatar Mar 30 '20 07:03 poke

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

stale[bot] avatar Jul 21 '21 02:07 stale[bot]

Please keep it open for now. I forgot about this but would still like to give it a shot eventually.

poke avatar Jul 24 '21 09:07 poke

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

github-actions[bot] avatar Jul 25 '22 02:07 github-actions[bot]

Please keep it open for now. I forgot about this but would still like to give it a shot eventually.

Pinging myself 😅😅

poke avatar Jul 25 '22 05:07 poke

This issue has been automatically marked as stale because it has no recent activity. It will be closed if no further activity occurs. Please comment if you believe this should remain open, otherwise it will be closed in 14 days. Thank you for your contributions to this project.

github-actions[bot] avatar Jul 27 '23 01:07 github-actions[bot]

Closing due to inactivity. If you are looking at this issue in the future and think it should be reopened, please make a commented here and mention natemcmaster so he sees the notification.

github-actions[bot] avatar Aug 10 '23 01:08 github-actions[bot]