Skip to content

Commit ce54d76

Browse files
eisbaer66jonsequitur
authored andcommitted
using ReflectedType instead of DeclaringType
in ModelBindingCommandHandler and MethodInfoHandlerDescriptor as suggested by aayjaychan
1 parent 18069a6 commit ce54d76

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

src/System.CommandLine.Hosting.Tests/HostingHandlerTest.cs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,50 @@ public static async Task Can_bind_to_arguments_via_injection()
113113
service.StringValue.Should().Be("TEST");
114114
}
115115

116+
[Fact]
117+
public static async Task Invokes_DerivedClass()
118+
{
119+
var service = new MyService();
120+
121+
var cmd = new RootCommand();
122+
cmd.AddCommand(new MyCommand());
123+
cmd.AddCommand(new MyOtherCommand());
124+
var parser = new CommandLineBuilder(cmd)
125+
.UseHost((builder) => {
126+
builder.ConfigureServices(services =>
127+
{
128+
services.AddTransient(x => service);
129+
})
130+
.UseCommandHandler<MyCommand, MyCommand.MyDerivedHandler>()
131+
.UseCommandHandler<MyOtherCommand, MyOtherCommand.MyDerivedHandler>();
132+
})
133+
.Build();
134+
135+
await parser.InvokeAsync(new string[] { "mycommand", "--int-option", "54" });
136+
service.Value.Should().Be(54);
137+
138+
await parser.InvokeAsync(new string[] { "myothercommand", "TEST" });
139+
service.StringValue.Should().Be("TEST");
140+
}
141+
142+
public abstract class MyBaseHandler : ICommandHandler
143+
{
144+
public int IntOption { get; set; } // bound from option
145+
public IConsole Console { get; set; } // bound from DI
146+
147+
public int Invoke(InvocationContext context)
148+
{
149+
return Act();
150+
}
151+
152+
public Task<int> InvokeAsync(InvocationContext context)
153+
{
154+
return Task.FromResult(Act());
155+
}
156+
157+
protected abstract int Act();
158+
}
159+
116160
public class MyCommand : Command
117161
{
118162
public MyCommand() : base(name: "mycommand")
@@ -144,6 +188,22 @@ public Task<int> InvokeAsync(InvocationContext context)
144188
return Task.FromResult(IntOption);
145189
}
146190
}
191+
192+
public class MyDerivedHandler : MyBaseHandler
193+
{
194+
private readonly MyService service;
195+
196+
public MyDerivedHandler(MyService service)
197+
{
198+
this.service = service;
199+
}
200+
201+
protected override int Act()
202+
{
203+
service.Value = IntOption;
204+
return IntOption;
205+
}
206+
}
147207
}
148208

149209
public class MyOtherCommand : Command
@@ -177,6 +237,25 @@ public Task<int> InvokeAsync(InvocationContext context)
177237
return Task.FromResult(service.Action?.Invoke() ?? 0);
178238
}
179239
}
240+
241+
public class MyDerivedHandler : MyBaseHandler
242+
{
243+
private readonly MyService service;
244+
245+
public MyDerivedHandler(MyService service)
246+
{
247+
this.service = service;
248+
}
249+
250+
public string One { get; set; }
251+
252+
protected override int Act()
253+
{
254+
service.Value = IntOption;
255+
service.StringValue = One;
256+
return service.Action?.Invoke() ?? 0;
257+
}
258+
}
180259
}
181260

182261
public class MyService

src/System.CommandLine.NamingConventionBinder/MethodInfoHandlerDescriptor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public override ICommandHandler GetCommandHandler()
4040
}
4141
}
4242

43-
public override ModelDescriptor Parent => ModelDescriptor.FromType(_handlerMethodInfo.DeclaringType);
43+
public override ModelDescriptor Parent => ModelDescriptor.FromType(_handlerMethodInfo.ReflectedType);
4444

4545
private protected override IEnumerable<ParameterDescriptor> InitializeParameterDescriptors() =>
4646
_handlerMethodInfo.GetParameters()

src/System.CommandLine.NamingConventionBinder/ModelBindingCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public async Task<int> InvokeAsync(InvocationContext context)
7373
if (_handlerDelegate is null)
7474
{
7575
var invocationTarget = _invocationTarget ??
76-
bindingContext.GetService(_handlerMethodInfo!.DeclaringType);
76+
bindingContext.GetService(_handlerMethodInfo!.ReflectedType);
7777
if(invocationTarget is { })
7878
{
7979
_invocationTargetBinder?.UpdateInstance(invocationTarget, bindingContext);

0 commit comments

Comments
 (0)