#.net #.net-core #console-application #ihostedservice
#.net #.net-ядро #консольное приложение #ихостедсервис
Вопрос:
Я не могу понять, как получить доступ к аргументам командной строки в моем ConsoleHostedService
классе реализации. Я вижу, что в источниках CreateDefaultBuilder(args)
каким-то образом добавляется это в конфигурацию … с именем Args
…
Наличие основной программы:
internal sealed class Program
{
private static async Task Main(string[] args)
{
await Host.CreateDefaultBuilder(args)
.UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.ConfigureServices((context, services) =>
{
services.AddHostedService<ConsoleHostedService>();
})
.RunConsoleAsync();
}
}
и размещенный сервис:
internal sealed class ConsoleHostedService : IHostedService
{
public ConsoleHostedService(
IHostApplicationLifetime appLifetime,
IServiceProvider serviceProvider)
{
//...
}
}
Комментарии:
1.
System.Environment.GetCommandLineArguments()
?2. Это зависит от того, что вы на самом деле пытаетесь извлечь из командной строки. Приведите пример варианта использования
3. @Nkosi: У меня такое чувство, что этого определенно не должно быть. Я хотел бы получить доступ к массиву args таким, какой он есть
4. @Dai Спасибо, это будет запасной план, хотя, вероятно, это не тот. ЧИСТЫЙ предполагаемый способ, если только не было бы
CreateDefaultBuilder(args)
вызвано точноmain
‘sargs
. Кроме тогоEnvironment.CommandLine
, это монолитная строка, конечно, я могу разделить ее на пробел, но она была бы менее подвержена ошибкам и более совместима, если бы я получил исходный массив OS5. Тот, который передается в configuration, предназначен для обеспечения привязки конфигурации к строгим типам через CommandLineConfigurationProvider docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration /…
Ответ №1:
Я не верю, что существует встроенный метод DI для получения аргументов командной строки, но, вероятно, причина в том, что обработка аргументов командной строки является обязанностью вашего хост-приложения, и это должно передавать информацию о хосте / среде через IConfiguration
и т.д. IOptions
В любом случае, просто определите свои собственные вводимые:
public interface IEntrypointInfo
{
String CommandLine { get; }
IReadOnlyList<String> CommandLineArgs { get; }
// Default interface implementation, requires C# 8.0 or later:
Boolean HasFlag( String flagName )
{
return this.CommandLineArgs.Any( a => ( "-" a ) == flagName || ( "/" a ) == flagName );
}
}
/// <summary>Implements <see cref="IEntrypointInfo"/> by exposing data provided by <see cref="System.Environment"/>.</summary>
public class SystemEnvironmentEntrypointInfo : IEntrypointInfo
{
public String CommandLine => System.Environment.CommandLine;
public IReadOnlyList<String> CommandLineArgs => System.Environment.GetCommandLineArgs();
}
/// <summary>Implements <see cref="IEntrypointInfo"/> by exposing provided data.</summary>
public class SimpleEntrypointInfo : IEntrypointInfo
{
public SimpleEntrypointInfo( String commandLine, String[] commandLineArgs )
{
this.CommandLine = commandLine ?? throw new ArgumentNullException(nameof(commandLine));
this.CommandLineArgs = commandLineArgs ?? throw new ArgumentNullException(nameof(commandLineArgs));
}
public String CommandLine { get; }
public IReadOnlyList<String> CommandLineArgs { get; }
}
//
public static class Program
{
public static async Task Main( String[] args )
{
await Host.CreateDefaultBuilder( args )
.UseContentRoot(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.ConfigureServices((context, services) =>
{
services.AddHostedService<ConsoleHostedService>();
services.AddSingleton<IEntrypointInfo,SystemEnvironmentEntrypointInfo>()
})
.RunConsoleAsync();
}
Для автоматизированных модульных и интеграционных тестов используйте SimpleEntrypointInfo
.