The CreateDefaultBuilder
adds a CommandLineConfigurationProvider
to its configuration providers but you wouldn't normally access it directly. Instead, add an IConfiguration
parameter to your ConsoleHostedService
constructor and you will automatically receive settings from several settings sources, including command line arguments:
internal sealed class ConsoleHostedService : IHostedService
{
public ConsoleHostedService(
IHostApplicationLifetime appLifetime,
IServiceProvider serviceProvider,
IConfiguration configuration)
{
// Get the value as a string
string argValueString = configuration["MyFirstArg"]
// Or if it's an integer
int argValueInt = configuration.GetValue<int>("MyFirstArg")
}
}
This does require that your command line arguments follow the prescribed format as defined here:
MyFirstArg=12345
/MyFirstArg 12345
--MyFirstArg 12345
However...
If you really must get the actual command line args and, if you don't mind relying on the implementation of the default builder, you could do this:
Create a custom CommandLineConfigurationProvider
class and expose its Data
and Args
properties:
public class ExposedCommandLineConfigurationProvider : CommandLineConfigurationProvider
{
public ExposedCommandLineConfigurationProvider(IEnumerable<string> args, IDictionary<string, string> switchMappings = null)
:base(args, switchMappings)
{
}
public new IDictionary<string, string> Data => base.Data;
public new IEnumerable<string> Args => base.Args;
}
Then in your main program, add it to the lst of existing configuration providers:
internal sealed class Program
{
private static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
.UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.ConfigureAppConfiguration(config => config
.Add(new ExposedCommandLineConfigurationSource { Args = args }))
.ConfigureServices((context, services) => services
.AddHostedService<SchedulerWorker>())
.RunConsoleAsync();
}
}
Finally, dig your arguments provider out of the IConfiguration provided to you ConsoleHostedService:
internal sealed class ConsoleHostedService : IHostedService
{
public ConsoleHostedService(
IHostApplicationLifetime appLifetime,
IServiceProvider serviceProvider,
IConfiguration configuration)
{
if (configuration is ConfigurationRoot configRoot)
{
var provider = configRoot.Providers.OfType<ExposedCommandLineConfigurationProvider>().Single();
var rawArgs = provider.Args;
var namedArgs = provider.Data;
}
else
{
// Handle this unlikely situation
}
}
}
But for something that can be otherwise done so simply, that seems like a lot of work (and potentially breakable by any changes in the implementation of the default builder).
System.Environment.GetCommandLineArguments()
? – PlataCreateDefaultBuilder(args)
called exactly themain
'sargs
. Also theEnvironment.CommandLine
is a monolitic string, of course I can split it by space, but it would be less error prone and more compatible if I got the original OS array – Aparri