如何使用 IHostedService 访问控制台应用程序中的命令行参数?

g.p*_*dou 7 .net console-application .net-core ihostedservice

我无法弄清楚如何访问我的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

和托管服务:

internal sealed class ConsoleHostedService : IHostedService
{
    public ConsoleHostedService(
        IHostApplicationLifetime appLifetime,
        IServiceProvider serviceProvider)
    {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

Dai*_*Dai 4

我不相信有内置的DI 方法来获取命令行参数 - 但处理命令行参数的原因可能是主机应用程序的责任,并且应该在 via 等中传递主机/环境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();
    }
Run Code Online (Sandbox Code Playgroud)

对于自动化单元和集成测试,请使用SimpleEntrypointInfo.