Add multiple inheritance support through interfaces (#120)

This commit is contained in:
AliReZa Sabouri
2022-01-09 19:41:42 +03:30
committed by GitHub
parent 21bc69d116
commit ae2d4299f0
2 changed files with 68 additions and 3 deletions

View File

@@ -704,4 +704,64 @@ public class Command : ICommand
exitCode.Should().NotBe(0);
stdErr.Should().Contain("expects a single argument, but provided with multiple");
}
[Fact]
public async Task Option_bound_using_interfaces_for_multiple_inheritance_should_work()
{
// Arrange
var commandType = DynamicCommandBuilder.Compile(
// language=cs
@"
public static class FooBarLogger
{
public static bool Foo { get; set; } = false;
public static bool Bar { get; set; } = false;
}
public interface IOptionBar : ICommand
{
[CommandOption(""bar"")]
public bool Bar
{
get => FooBarLogger.Bar;
set => FooBarLogger.Bar = value;
}
}
public interface IOptionFoo : ICommand
{
[CommandOption(""foo"")]
public bool Foo
{
get => FooBarLogger.Foo;
set => FooBarLogger.Foo = value;
}
}
[Command]
public class Command : IOptionFoo, IOptionBar
{
public ValueTask ExecuteAsync(IConsole console)
{
console.Output.WriteLine($""Foo: { FooBarLogger.Foo }"");
console.Output.WriteLine($""Bar: { FooBarLogger.Bar }"");
return default;
}
}
");
var application = new CliApplicationBuilder()
.AddCommand(commandType)
.UseConsole(FakeConsole)
.Build();
// Act
var exitCode = await application.RunAsync(
new[] {"--foo" , "--bar"});
var stdOut = FakeConsole.ReadOutputString();
// Assert
exitCode.Should().Be(0);
stdOut.Trim().Should().Be("Foo: True\r\nBar: True");
}
}

View File

@@ -86,13 +86,18 @@ internal partial class CommandSchema
var implicitOptionSchemas = string.IsNullOrWhiteSpace(name)
? new[] {OptionSchema.HelpOption, OptionSchema.VersionOption}
: new[] {OptionSchema.HelpOption};
var parameterSchemas = type.GetProperties()
// Include interface members for multiple inheritance
// If interface inherits from ICommand, it will be included
var interfaces = type.GetInterfaces().Where(i => i != typeof(ICommand) && typeof(ICommand).IsAssignableFrom(i) );
var properties = type.GetProperties().Concat(interfaces.SelectMany(i => i.GetProperties())).ToArray();
var parameterSchemas = properties
.Select(ParameterSchema.TryResolve)
.WhereNotNull()
.ToArray();
var optionSchemas = type.GetProperties()
var optionSchemas = properties
.Select(OptionSchema.TryResolve)
.WhereNotNull()
.Concat(implicitOptionSchemas)