如何使用 IHostedService 访问控制台应用程序中的命令行参数?
How can I access the command line arguments in a console application using IHostedService?
我不知道如何在我的 ConsoleHostedService
实现 class 中访问命令行参数。我在来源中看到 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)
{
//...
}
}
我不相信有内置 DI 方法来获取命令行参数 - 但处理命令行参数可能是您的主机负责的原因应用程序,应该通过 IConfiguration
和 IOptions
等传递 host/environment 信息
无论如何,只需定义您自己的注射剂:
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
。
我不知道如何在我的 ConsoleHostedService
实现 class 中访问命令行参数。我在来源中看到 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)
{
//...
}
}
我不相信有内置 DI 方法来获取命令行参数 - 但处理命令行参数可能是您的主机负责的原因应用程序,应该通过 IConfiguration
和 IOptions
等传递 host/environment 信息
无论如何,只需定义您自己的注射剂:
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
。