@@ -9,11 +9,13 @@ internal static class OptionSchemaBuilder
99 public static OptionSchema Build (
1010 RouteTemplate template ,
1111 CommandBuilder command ,
12- ParsingOptions parsingOptions )
12+ ParsingOptions parsingOptions ,
13+ ImplicitServiceParameterRegistry implicitServiceParameters )
1314 {
1415 ArgumentNullException . ThrowIfNull ( template ) ;
1516 ArgumentNullException . ThrowIfNull ( command ) ;
1617 ArgumentNullException . ThrowIfNull ( parsingOptions ) ;
18+ ArgumentNullException . ThrowIfNull ( implicitServiceParameters ) ;
1719
1820 var routeParameterNames = template . Segments
1921 . OfType < DynamicRouteSegment > ( )
@@ -25,7 +27,7 @@ public static OptionSchema Build(
2527 var groupPositionalPropertyNames = new List < string > ( ) ;
2628 foreach ( var parameter in command . Handler . Method . GetParameters ( ) )
2729 {
28- if ( ShouldSkipSchemaParameter ( parameter , routeParameterNames ) )
30+ if ( ShouldSkipSchemaParameter ( parameter , routeParameterNames , implicitServiceParameters ) )
2931 {
3032 continue ;
3133 }
@@ -57,11 +59,29 @@ public static OptionSchema Build(
5759
5860 private static bool ShouldSkipSchemaParameter (
5961 ParameterInfo parameter ,
60- HashSet < string > routeParameterNames )
62+ HashSet < string > routeParameterNames ,
63+ ImplicitServiceParameterRegistry implicitServiceParameters )
6164 {
65+ var optionAttribute = parameter . GetCustomAttribute < ReplOptionAttribute > ( inherit : true ) ;
66+ var argumentAttribute = parameter . GetCustomAttribute < ReplArgumentAttribute > ( inherit : true ) ;
67+ if ( implicitServiceParameters . TryGetGlobalOptionsServiceType ( parameter . ParameterType , out var globalOptionsType ) )
68+ {
69+ if ( optionAttribute is not null || argumentAttribute is not null )
70+ {
71+ var attributeName = optionAttribute is not null
72+ ? nameof ( ReplOptionAttribute ) . Replace ( "Attribute" , string . Empty , StringComparison . Ordinal )
73+ : nameof ( ReplArgumentAttribute ) . Replace ( "Attribute" , string . Empty , StringComparison . Ordinal ) ;
74+ throw new InvalidOperationException (
75+ $ "Parameter '{ parameter . Name } ' uses typed global options '{ globalOptionsType . Name } ' registered through "
76+ + $ "UseGlobalOptions<T>() and cannot declare [{ attributeName } ]. Remove the attribute or use a separate command options type.") ;
77+ }
78+
79+ return true ;
80+ }
81+
6282 if ( string . IsNullOrWhiteSpace ( parameter . Name )
6383 || parameter . ParameterType == typeof ( CancellationToken )
64- || IsFrameworkInjectedParameter ( parameter )
84+ || implicitServiceParameters . IsImplicitServiceParameter ( parameter . ParameterType )
6585 || parameter . GetCustomAttribute < FromContextAttribute > ( ) is not null
6686 || parameter . GetCustomAttribute < FromServicesAttribute > ( ) is not null )
6787 {
@@ -73,8 +93,6 @@ private static bool ShouldSkipSchemaParameter(
7393 return false ;
7494 }
7595
76- var optionAttribute = parameter . GetCustomAttribute < ReplOptionAttribute > ( inherit : true ) ;
77- var argumentAttribute = parameter . GetCustomAttribute < ReplArgumentAttribute > ( inherit : true ) ;
7896 if ( optionAttribute is null && argumentAttribute is null )
7997 {
8098 return true ;
@@ -190,19 +208,6 @@ private static void AppendValueAliases(
190208 }
191209 }
192210
193- private static bool IsFrameworkInjectedParameter ( ParameterInfo parameter ) =>
194- parameter . ParameterType == typeof ( IServiceProvider )
195- || parameter . ParameterType == typeof ( ICoreReplApp )
196- || parameter . ParameterType == typeof ( CoreReplApp )
197- || parameter . ParameterType == typeof ( IReplSessionState )
198- || parameter . ParameterType == typeof ( IReplInteractionChannel )
199- || parameter . ParameterType == typeof ( IReplIoContext )
200- || parameter . ParameterType == typeof ( IReplKeyReader )
201- || string . Equals ( parameter . ParameterType . FullName , "Repl.Mcp.IMcpClientRoots" , StringComparison . Ordinal )
202- || string . Equals ( parameter . ParameterType . FullName , "Repl.Mcp.IMcpSampling" , StringComparison . Ordinal )
203- || string . Equals ( parameter . ParameterType . FullName , "Repl.Mcp.IMcpElicitation" , StringComparison . Ordinal )
204- || string . Equals ( parameter . ParameterType . FullName , "Repl.Mcp.IMcpFeedback" , StringComparison . Ordinal ) ;
205-
206211 private static ReplArity ResolveArity ( ParameterInfo parameter , ReplOptionAttribute ? optionAttribute )
207212 {
208213 if ( optionAttribute ? . Arity is { } explicitArity )
0 commit comments