[red]Invalid usage[/]
Unhandled exception. System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.MethodBase.ValidateInvokeTarget(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeOneParameter(Object obj, BindingFlags invokeAttr, Binder binder, Object parameter, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.PropertyInfo.SetValue(Object obj, Object value)
at Oakton.Parsing.TokenHandlerBase.setValue(Object target, Object value)
at Oakton.Argument.Handle(Object input, Queue1 tokens) at Oakton.Help.UsageGraph.<>c__DisplayClass20_0.<BuildInput>b__0(ITokenHandler h) at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable1 source, Func2 predicate, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source, Func2 predicate) at Oakton.Help.UsageGraph.BuildInput(Queue1 tokens, ICommandCreator creator)
at Oakton.CommandFactory.HelpRun(Queue1 queue) at Oakton.CommandFactory.HelpRun(String commandName) at Oakton.CommandFactory.buildRun(Queue1 queue, String commandName)
at Oakton.CommandFactory.BuildRun(IEnumerable`1 args)
at Oakton.CommandExecutor.ExecuteAsync(String[] args)
at Oakton.CommandExecutor.Execute(String[] args)
at Program.$(String[] args) in C:\Users\Joe\source\MyConsoleApp\Program.cs:line 33
dotnet run -- myconsoleapp ?
In addition if you specify the wrong arguments trying to run your console app, you also get a hard error. This command:
dotnet run --myconsoleapp test123
Gives this error:
[red]Error parsing input[/]System.FormatException: The input string 'test123' was not in a correct format.
at void System.Number.ThrowOverflowOrFormatException(ParsingStatus status, ReadOnlySpan value, TypeCode type)
at int System.Int32.Parse(string s)
at object Oakton.Internal.Conversion.Conversions.<>cDisplayClass5_0`1.b0(string x)
at bool Oakton.Argument.Handle(object input, Queue tokens)
at bool Oakton.Help.UsageGraph.<>cDisplayClass20_0.b0(ITokenHandler h)
at TSource System.Linq.Enumerable.TryGetFirst(IEnumerable source, Func<TSource, bool> predicate, out bool found)
at TSource System.Linq.Enumerable.FirstOrDefault(IEnumerable source, Func<TSource, bool> predicate)
at object Oakton.Help.UsageGraph.BuildInput(Queue tokens, ICommandCreator creator)
at CommandRun Oakton.CommandFactory.buildRun(Queue queue, string commandName)
Unhandled exception. System.Reflection.TargetException: Non-static method requires a target.
at System.Reflection.MethodBase.ValidateInvokeTarget(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeOneParameter(Object obj, BindingFlags invokeAttr, Binder binder, Object parameter, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.PropertyInfo.SetValue(Object obj, Object value)
at Oakton.Parsing.TokenHandlerBase.setValue(Object target, Object value)
at Oakton.Argument.Handle(Object input, Queue1 tokens) at Oakton.Help.UsageGraph.<>c__DisplayClass20_0.<BuildInput>b__0(ITokenHandler h) at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable1 source, Func2 predicate, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1 source, Func2 predicate) at Oakton.Help.UsageGraph.BuildInput(Queue1 tokens, ICommandCreator creator)
at Oakton.CommandFactory.HelpRun(Queue1 queue) at Oakton.CommandFactory.HelpRun(String commandName) at Oakton.CommandFactory.buildRun(Queue1 queue, String commandName)
at Oakton.CommandFactory.BuildRun(IEnumerable`1 args)
at Oakton.CommandExecutor.ExecuteAsync(String[] args)
at Oakton.CommandExecutor.Execute(String[] args)
at Program.$(String[] args) in C:\Users\Joe\source\MyConsoleApp\Program.cs:line 33
As long as I specify the proper parameter, Oakton does work. It is just when I try to take advantage of the improved run command to see how the command/inputs are supposed to be structured or if I make a mistake on the input parameters, Oakton seems to crash hard.
I am using version 6.0.0 of Oakton and a .NET 7 console app. My program.cs looks like this:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Oakton;
using Oakton.Commands;
using System.Reflection;
var executor = CommandExecutor.For(commandFactory =>
{
commandFactory.RegisterCommands(typeof(Program).GetTypeInfo().Assembly);
}
, new DiCommandCreator(host.Services)
);
return executor.Execute(args);
Any my DiCommandCreator class looks like this:
public class DiCommandCreator : ICommandCreator
{
private readonly IServiceProvider serviceProvider;
public DiCommandCreator(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public IOaktonCommand CreateCommand(Type commandType)
{
return (IOaktonCommand)serviceProvider.GetService(commandType);
}
public object CreateModel(Type modelType)
{
return serviceProvider.GetService(modelType);
}
}
I dont think it is anything wrong per se with my command or input (which is just a simple class with one integer property) because if I switch over to not use dependency injection and just use the "RunOaktonCommandsSynchronously" approach, everything works.
Seems like when using the custom command pattern, Oakton just does not work as expected? I need to use IOC in this project and hoping there may be some way to address these issues. Thank you.
Hey, sorry, honestly just seeing this. The idiomatic way now is to just spin up the IHost through a NetInput and use the application's main container. Would that help? That's all I use Oakton for at this point.
When using the custom command pattern, as described here: https://jasperfx.github.io/oakton/guide/bootstrapping.html#custom-command-creators
The functionality as described in the "Improved Run Command" described here: https://jasperfx.github.io/oakton/guide/host/run.html#improved-run-command does not work. Instead of being able to see your commands or see their usage, you get an error.
For example if I execute this command:
dotnet run -- myconsoleapp
I get this error:
[red]Invalid usage[/] Unhandled exception. System.Reflection.TargetException: Non-static method requires a target. at System.Reflection.MethodBase.ValidateInvokeTarget(Object target) at System.Reflection.RuntimeMethodInfo.InvokeOneParameter(Object obj, BindingFlags invokeAttr, Binder binder, Object parameter, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) at System.Reflection.PropertyInfo.SetValue(Object obj, Object value) at Oakton.Parsing.TokenHandlerBase.setValue(Object target, Object value) at Oakton.Argument.Handle(Object input, Queue$(String[] args) in C:\Users\Joe\source\MyConsoleApp\Program.cs:line 33
1 tokens) at Oakton.Help.UsageGraph.<>c__DisplayClass20_0.<BuildInput>b__0(ITokenHandler h) at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable
1 source, Func2 predicate, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source, Func2 predicate) at Oakton.Help.UsageGraph.BuildInput(Queue
1 tokens, ICommandCreator creator) at Oakton.CommandFactory.HelpRun(Queue1 queue) at Oakton.CommandFactory.HelpRun(String commandName) at Oakton.CommandFactory.buildRun(Queue
1 queue, String commandName) at Oakton.CommandFactory.BuildRun(IEnumerable`1 args) at Oakton.CommandExecutor.ExecuteAsync(String[] args) at Oakton.CommandExecutor.Execute(String[] args) at Program.dotnet run -- myconsoleapp ?
In addition if you specify the wrong arguments trying to run your console app, you also get a hard error. This command:
dotnet run --myconsoleapp test123
Gives this error:
[red]Error parsing input[/]System.FormatException: The input string 'test123' was not in a correct format. at void System.Number.ThrowOverflowOrFormatException(ParsingStatus status, ReadOnlySpan value, TypeCode type)
at int System.Int32.Parse(string s)
at object Oakton.Internal.Conversion.Conversions.<>cDisplayClass5_0`1.b0(string x)
at bool Oakton.Argument.Handle(object input, Queue tokens)
at bool Oakton.Help.UsageGraph.<>c DisplayClass20_0.b 0(ITokenHandler h)
at TSource System.Linq.Enumerable.TryGetFirst(IEnumerable source, Func<TSource, bool> predicate, out bool found)
at TSource System.Linq.Enumerable.FirstOrDefault(IEnumerable source, Func<TSource, bool> predicate)
at object Oakton.Help.UsageGraph.BuildInput(Queue tokens, ICommandCreator creator)
at CommandRun Oakton.CommandFactory.buildRun(Queue queue, string commandName)
Unhandled exception. System.Reflection.TargetException: Non-static method requires a target. at System.Reflection.MethodBase.ValidateInvokeTarget(Object target) at System.Reflection.RuntimeMethodInfo.InvokeOneParameter(Object obj, BindingFlags invokeAttr, Binder binder, Object parameter, CultureInfo culture) at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) at System.Reflection.PropertyInfo.SetValue(Object obj, Object value) at Oakton.Parsing.TokenHandlerBase.setValue(Object target, Object value) at Oakton.Argument.Handle(Object input, Queue$(String[] args) in C:\Users\Joe\source\MyConsoleApp\Program.cs:line 33
1 tokens) at Oakton.Help.UsageGraph.<>c__DisplayClass20_0.<BuildInput>b__0(ITokenHandler h) at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable
1 source, Func2 predicate, Boolean& found) at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source, Func2 predicate) at Oakton.Help.UsageGraph.BuildInput(Queue
1 tokens, ICommandCreator creator) at Oakton.CommandFactory.HelpRun(Queue1 queue) at Oakton.CommandFactory.HelpRun(String commandName) at Oakton.CommandFactory.buildRun(Queue
1 queue, String commandName) at Oakton.CommandFactory.BuildRun(IEnumerable`1 args) at Oakton.CommandExecutor.ExecuteAsync(String[] args) at Oakton.CommandExecutor.Execute(String[] args) at Program.As long as I specify the proper parameter, Oakton does work. It is just when I try to take advantage of the improved run command to see how the command/inputs are supposed to be structured or if I make a mistake on the input parameters, Oakton seems to crash hard.
I am using version 6.0.0 of Oakton and a .NET 7 console app. My program.cs looks like this:
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Oakton; using Oakton.Commands; using System.Reflection;
using IHost host = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddTransient();
services.AddTransient();
})
//.ConfigureAppConfiguration((hostingContext, config) => { })
.Build();
var executor = CommandExecutor.For(commandFactory => { commandFactory.RegisterCommands(typeof(Program).GetTypeInfo().Assembly); } , new DiCommandCreator(host.Services) ); return executor.Execute(args);
Any my DiCommandCreator class looks like this:
I dont think it is anything wrong per se with my command or input (which is just a simple class with one integer property) because if I switch over to not use dependency injection and just use the "RunOaktonCommandsSynchronously" approach, everything works.
return Host.CreateDefaultBuilder(args) .RunOaktonCommandsSynchronously(args);
Seems like when using the custom command pattern, Oakton just does not work as expected? I need to use IOC in this project and hoping there may be some way to address these issues. Thank you.