Integration with Generic Host
The McMaster.Extensions.Hosting.CommandLine package provides support for integrating command line parsing with .NET's generic host.
Get started
To get started, install the McMaster.Extensions.Hosting.CommandLine
package.
The main usage for generic host is RunCommandLineApplicationAsync<TApp>(args)
, where TApp
is a class
which will be bound to command line arguments and options using attributes and CommandLineApplication.Execute<T>
.
Sample
This minimal sample shows how to take advantage of generic host features, such as IHostingEnvironment
,
as well as command line parsing options with this library.
using System;
using System.Threading.Tasks;
using McMaster.Extensions.CommandLineUtils;
using Microsoft.Extensions.Hosting;
class Program
{
static Task<int> Main(string[] args)
=> new HostBuilder()
.RunCommandLineApplicationAsync<Program>(args);
[Option]
public int Port { get; } = 8080;
private IHostingEnvironment _env;
public Program(IHostingEnvironment env)
{
_env = env;
}
private void OnExecute()
{
Console.WriteLine($"Starting on port {Port}, env = {_env.EnvironmentName}");
}
}
Dependency injection
Generic host integration allows you to use the most current DI configuration approach indicated by the aspnet project. The basic approach starts by creating the builder:
return await new HostBuilder()
Then you can configure your features:
.ConfigureLogging((context, builder) =>
{
builder.AddConsole();
})
.ConfigureServices((context, services) => {
services.AddSingleton<IGreeter, Greeter>()
.AddSingleton<IConsole>(PhysicalConsole.Singleton);
})
And finally, run your program:
.RunCommandLineApplicationAsync<Program>(args);
Below is the full source code for the generic host services example. Notice that instance of IGreeter
will be injected into the Program
constructor thanks to the dependency injection.
using System;
using Microsoft.Extensions.DependencyInjection;
using McMaster.Extensions.CommandLineUtils;
namespace CustomServices
{
#region Program
[Command(Name = "di", Description = "Dependency Injection sample project")]
[HelpOption]
class Program
{
public static int Main(string[] args)
{
var services = new ServiceCollection()
.AddSingleton<IMyService, MyServiceImplementation>()
.AddSingleton<IConsole>(PhysicalConsole.Singleton)
.BuildServiceProvider();
var app = new CommandLineApplication<Program>();
app.Conventions
.UseDefaultConventions()
.UseConstructorInjection(services);
return app.Execute(args);
}
private readonly IMyService _myService;
public Program(IMyService myService)
{
_myService = myService;
}
private void OnExecute()
{
_myService.Invoke();
}
}
#endregion
#region IMyService
interface IMyService
{
void Invoke();
}
#endregion
#region MyServiceImplementation
class MyServiceImplementation : IMyService
{
private readonly IConsole _console;
public MyServiceImplementation(IConsole console)
{
_console = console;
}
public void Invoke()
{
_console.WriteLine("Hello dependency injection!");
}
}
#endregion
}