dotnet / dotnet/command-line-api
Dependency injection confusion - How to use CommandLineBuilder, UseHost, CommandHandlers etc
- Dominant language
- C#
- Stars
- 3.7k
- Forks
- 428
- PR merge metrics
- No merged PRs in 30d
Description
I'm lost in the weeds with dependency injection here.
```csharp
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();
}).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 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 https://github.com/dotnet/command-line-api/issues/1025#issuecomment-678609352 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();
s.Configure(c => c.ConnectionString = "Data Source=mydatabase.db");
//Bind --host 127.0.0.1 to configuration somehow
//s.Configure(h=> h.Host = ParseResult.GetOption(...))
s.AddSingleton();
}).UseCommandHandler()).Build();
```
So I am stuck on:
1. Parsing command line options and arguments
2. Getting access to services in an IHost's ServiceCollection
3. Converting command lines to configuration for services
4. Invoking it all and having it "just work"
Thanks in advance - sorry if I've completely missed the mark here.
Contributor guide
Assessment
This issue has not been assessed yet.