Description
I'm lost in the weeds with dependency injection here.
using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Hosting;
using System.CommandLine.Invocation;
using System.CommandLine.Parsing;
namespace Test2
{
internal class Program
{
static void Main(string[] args)
{
CommandLineBuilder builder = new CommandLineBuilder();
var parser = builder.UseHost((host) => {
host.UseCommandHandler<MyCommand, MyCommandHandler>();
}).Build();
var parseResult = parser.Parse(args);
var invokeResult = parser.Invoke(args);
}
}
internal class MyCommandHandler : ICommandHandler
{
public int Invoke(InvocationContext context)
{
throw new NotImplementedException();
}
public Task<int> InvokeAsync(InvocationContext context)
{
throw new NotImplementedException();
}
}
internal class MyCommand : Command
{
public MyCommand() : base("Test2")
{
}
}
public interface IHelloService
{
string Hello();
}
public class HelloService : IHelloService
{
public HelloService()
{
}
public string Hello()
{
return "Hello!";
}
}
}
Before I even get to using the Hosting stuff, why is RootCommand set to Test2 when that's not in args[]
and why aren't MyCommand
and MyCommandHandler
not called at all - shouldn't I be getting a NotImplementedException
?
I've looked at https://github.com/dotnet/command-line-api/blob/5618b2d243ccdeb5c7e50a298b33b13036b4351b/src/System.CommandLine.Hosting.Tests/HostingHandlerTest.cs and #1025 (comment) but have not been able to make much progress.
https://learn.microsoft.com/en-us/dotnet/standard/commandline/dependency-injection isn't entirely suitable because I need multiple services after my command line is parsed.
Further away from my simplified example, I'd like something like the following to work:
var parser = commandBuilder.UseHost(host => host.ConfigureDefaults(args).ConfigureServices(s=>
{
s.AddLogging(l=> l.AddConsole());
s.AddOptions();
s.AddOptions<DatabaseOptions>();
s.Configure<DatabaseOptions>(c => c.ConnectionString = "Data Source=mydatabase.db");
//Bind --host 127.0.0.1 to configuration somehow
//s.Configure<RemoteHostOptions>(h=> h.Host = ParseResult.GetOption(...))
s.AddSingleton<IFilesDatabase, FilesDatabase>();
}).UseCommandHandler<ScanCommand, ScanCommandHandler>()).Build();
So I am stuck on:
- Parsing command line options and arguments
- Getting access to services in an IHost's ServiceCollection
- Converting command lines to configuration for services
- Invoking it all and having it "just work"
Thanks in advance - sorry if I've completely missed the mark here.