Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ System.CommandLine
public CommandLineBuilder UseHelp(System.Nullable<System.Int32> maxWidth = null)
public CommandLineBuilder UseHelp(System.String name, System.String[] helpAliases)
public CommandLineBuilder UseHelp(System.Action<System.CommandLine.Help.HelpContext> customize, System.Nullable<System.Int32> maxWidth = null)
public CommandLineBuilder UseHelpBuilder(System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> getHelpBuilder)
public CommandLineBuilder UseHelpBuilder(System.Func<System.CommandLine.Invocation.InvocationContext,System.CommandLine.Help.HelpBuilder> getHelpBuilder)
public CommandLineBuilder UseParseDirective(System.Int32 errorExitCode = 1)
public CommandLineBuilder UseParseErrorReporting(System.Int32 errorExitCode = 1)
public CommandLineBuilder UseSuggestDirective()
Expand All @@ -83,7 +83,7 @@ System.CommandLine
public CommandLineBuilder UseVersionOption(System.String name, System.String[] aliases)
public class CommandLineConfiguration
public static CommandLineBuilder CreateBuilder(Command rootCommand)
.ctor(Command command, System.Boolean enablePosixBundling = True, System.Boolean enableTokenReplacement = True, System.Collections.Generic.IReadOnlyList<System.CommandLine.Invocation.InvocationMiddleware> middlewarePipeline = null, System.Func<System.CommandLine.Binding.BindingContext,System.CommandLine.Help.HelpBuilder> helpBuilderFactory = null, System.CommandLine.Parsing.TryReplaceToken tokenReplacer = null)
.ctor(Command command, System.Boolean enablePosixBundling = True, System.Boolean enableTokenReplacement = True, System.Collections.Generic.IReadOnlyList<System.CommandLine.Invocation.InvocationMiddleware> middlewarePipeline = null, System.Func<System.CommandLine.Invocation.InvocationContext,System.CommandLine.Help.HelpBuilder> helpBuilderFactory = null, System.CommandLine.Parsing.TryReplaceToken tokenReplacer = null)
public System.Collections.Generic.IReadOnlyList<Directive> Directives { get; }
public System.Boolean EnablePosixBundling { get; }
public System.Boolean EnableTokenReplacement { get; }
Expand Down Expand Up @@ -172,24 +172,11 @@ System.CommandLine
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.CommandLine.Completions.CompletionContext context)
public System.String ToString()
System.CommandLine.Binding
public class BindingContext, System.IServiceProvider
public System.CommandLine.IConsole Console { get; }
public System.CommandLine.ParseResult ParseResult { get; }
public System.Void AddService(System.Type serviceType, System.Func<System.IServiceProvider,System.Object> factory)
public System.Void AddService<T>(Func<System.IServiceProvider,T> factory)
public System.Object GetService(System.Type serviceType)
public struct BoundValue : System.ValueType
public System.Object Value { get; }
public IValueDescriptor ValueDescriptor { get; }
public IValueSource ValueSource { get; }
public System.String ToString()
public interface IValueDescriptor
public System.Boolean HasDefaultValue { get; }
public System.String ValueName { get; }
public System.Type ValueType { get; }
public System.Object GetDefaultValue()
public interface IValueSource
public System.Boolean TryGetValue(IValueDescriptor valueDescriptor, BindingContext bindingContext, ref System.Object& boundValue)
System.CommandLine.Completions
public abstract class CompletionContext
public static CompletionContext Empty { get; }
Expand Down Expand Up @@ -253,7 +240,6 @@ System.CommandLine.Help
System.CommandLine.Invocation
public class InvocationContext
.ctor(System.CommandLine.ParseResult parseResult, System.CommandLine.IConsole console = null)
public System.CommandLine.Binding.BindingContext BindingContext { get; }
public System.CommandLine.IConsole Console { get; set; }
public System.Int32 ExitCode { get; set; }
public System.CommandLine.Help.HelpBuilder HelpBuilder { get; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,33 +136,29 @@ public async Task Can_generate_handler_with_well_know_parameters_types()
IConsole? boundConsole = null;
ParseResult? boundParseResult = null;
HelpBuilder? boundHelpBuilder = null;
BindingContext? boundBindingContext = null;

void Execute(
InvocationContext invocationContext,
IConsole console,
ParseResult parseResult,
HelpBuilder helpBuilder,
BindingContext bindingContext)
HelpBuilder helpBuilder)
{
boundInvocationContext = invocationContext;
boundConsole = console;
boundParseResult = parseResult;
boundHelpBuilder = helpBuilder;
boundBindingContext = bindingContext;
}

var command = new Command("command");

command.SetHandler<Action<InvocationContext, IConsole, ParseResult, HelpBuilder, BindingContext>>(Execute);
command.SetHandler<Action<InvocationContext, IConsole, ParseResult, HelpBuilder>>(Execute);

await command.InvokeAsync("command", _console);

boundInvocationContext.Should().NotBeNull();
boundConsole.Should().Be(_console);
boundParseResult.Should().NotBeNull();
boundHelpBuilder.Should().NotBeNull();
boundBindingContext.Should().NotBeNull();
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public BindingContextParameter(ITypeSymbol bindingContextType)
}

public override string GetValueFromContext()
=> "context.BindingContext";
=> "context.GetBindingContext()";

public override int GetHashCode()
=> base.GetHashCode();
Expand Down
6 changes: 2 additions & 4 deletions src/System.CommandLine.Generator/WellKnownTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ internal class WellKnownTypes
public INamedTypeSymbol ParseResult { get; }
public INamedTypeSymbol InvocationContext { get; }
public INamedTypeSymbol HelpBuilder { get; }
public INamedTypeSymbol BindingContext { get; }
public IEqualityComparer<ISymbol?> Comparer { get; }

public WellKnownTypes(Compilation compilation, IEqualityComparer<ISymbol?> comparer)
Expand All @@ -22,7 +21,6 @@ public WellKnownTypes(Compilation compilation, IEqualityComparer<ISymbol?> compa
ParseResult = GetType("System.CommandLine.ParseResult");
InvocationContext = GetType("System.CommandLine.Invocation.InvocationContext");
HelpBuilder = GetType("System.CommandLine.Help.HelpBuilder");
BindingContext = GetType("System.CommandLine.Binding.BindingContext");

INamedTypeSymbol GetType(string typeName)
=> compilation.GetTypeByMetadataName(typeName)
Expand Down Expand Up @@ -59,9 +57,9 @@ internal bool TryGet(ISymbol symbol, out Parameter? parameter)
return true;
}

if (Comparer.Equals(BindingContext, symbol))
if (symbol.MetadataName == "System.CommandLine.Binding.BindingContext" && symbol is INamedTypeSymbol bindingContext)
{
parameter = new BindingContextParameter(BindingContext);
parameter = new BindingContextParameter(bindingContext);
return true;
}

Expand Down
14 changes: 9 additions & 5 deletions src/System.CommandLine.Hosting/HostingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ public static CommandLineBuilder UseHost(this CommandLineBuilder builder,
{
config.AddCommandLineDirectives(invocation.ParseResult, configurationDirective);
});
var bindingContext = invocation.GetBindingContext();
hostBuilder.ConfigureServices(services =>
{
services.AddSingleton(invocation);
services.AddSingleton(invocation.BindingContext);
services.AddSingleton(bindingContext);
services.AddSingleton(invocation.Console);
services.AddTransient(_ => invocation.InvocationResult);
services.AddTransient(_ => invocation.ParseResult);
Expand All @@ -44,7 +45,7 @@ public static CommandLineBuilder UseHost(this CommandLineBuilder builder,

using var host = hostBuilder.Build();

invocation.BindingContext.AddService(typeof(IHost), _ => host);
bindingContext.AddService(typeof(IHost), _ => host);

await host.StartAsync(cancellationToken);

Expand Down Expand Up @@ -109,13 +110,16 @@ public static IHostBuilder UseCommandHandler(this IHostBuilder builder, Type com
&& invocation.ParseResult.CommandResult.Command is Command command
&& command.GetType() == commandType)
{
invocation.BindingContext.AddService(handlerType, c => c.GetService<IHost>().Services.GetService(handlerType));
builder.ConfigureServices(services =>
{
services.AddTransient(handlerType);
});

command.Handler = CommandHandler.Create(handlerType.GetMethod(nameof(ICommandHandler.InvokeAsync)));
BindingHandler bindingHandler = CommandHandler.Create(handlerType.GetMethod(nameof(ICommandHandler.InvokeAsync)));
// NullBindingHandler that accumulated services registered so far, before handler creation
bindingHandler.SetBindingContext(command.Handler is BindingHandler pre ? pre.GetBindingContext(invocation) : null);
command.Handler = bindingHandler;
bindingHandler.GetBindingContext(invocation).AddService(handlerType, c => c.GetService<IHost>().Services.GetService(handlerType));
}

return builder;
Expand Down Expand Up @@ -147,7 +151,7 @@ public static IHost GetHost(this InvocationContext invocationContext)
{
_ = invocationContext ?? throw new ArgumentNullException(paramName: nameof(invocationContext));
var hostModelBinder = new ModelBinder<IHost>();
return (IHost)hostModelBinder.CreateInstance(invocationContext.BindingContext);
return (IHost)hostModelBinder.CreateInstance(invocationContext.GetBindingContext());
}
}
}
Loading