2
2
// Imports
3
3
// ---------------------------------------------------------------------------------------------------------------------
4
4
using Microsoft . Extensions . DependencyInjection ;
5
+ using Microsoft . Extensions . Logging ;
6
+ using System . Diagnostics . CodeAnalysis ;
5
7
using System . Text . RegularExpressions ;
6
8
7
9
namespace CodeOfChaos . CliArgsParser ;
@@ -11,17 +13,19 @@ namespace CodeOfChaos.CliArgsParser;
11
13
public partial class CliParser : ICliParser {
12
14
public required Lazy < IServiceProvider > ? ServiceProvider { get ; init ; }
13
15
public required ICommandProvider CommandProvider { get ; init ; }
14
-
15
- [ GeneratedRegex ( @"\s+" ) ] private static partial Regex FindEmptySpacesRegex { get ; }
16
16
17
+ private ILogger < CliParser > ? Logger => ServiceProvider ? . Value . GetService < ILogger < CliParser > > ( ) ;
18
+
19
+ [ GeneratedRegex ( @"\s+" ) ] private static partial Regex FindEmptySpacesRegex { get ; }
20
+
17
21
// -----------------------------------------------------------------------------------------------------------------
18
22
// Methods
19
23
// -----------------------------------------------------------------------------------------------------------------
20
- internal CliParser ( ) { }
24
+ internal CliParser ( ) { }
21
25
public static CliParserBuilder CreateBuilder ( ) {
22
26
return new CliParserBuilder ( ) ;
23
27
}
24
-
28
+
25
29
public ValueTask ExecuteAsync ( string [ ] args , CancellationToken ct = default ) => ExecuteAsync ( ArgsInputHelper . ToOneLine ( args ) , ct ) ;
26
30
public async ValueTask ExecuteAsync ( string input , CancellationToken ct = default ) {
27
31
input = input . Replace ( "\\ \" " , "\" " ) ;
@@ -32,21 +36,47 @@ public async ValueTask ExecuteAsync(string input, CancellationToken ct = default
32
36
await Task . WhenAll ( tasks ) ;
33
37
return ;
34
38
}
35
-
39
+
36
40
string [ ] tokens = FindEmptySpacesRegex . Split ( input ) ;
37
41
string commandName = tokens [ 0 ] ;
38
42
string parameterInput = string . Join ( " " , tokens . Skip ( 1 ) ) ;
39
43
40
- if ( ! CommandProvider . TryGetCommand ( commandName , out Type ? commandType ) ) throw new Exception ( "no Command found" ) ;
41
-
42
- ICliCommand ? command = ServiceProvider is not null
43
- ? ( ICliCommand ? ) ActivatorUtilities . CreateInstance ( ServiceProvider . Value , commandType )
44
- : Activator . CreateInstance ( commandType ) as ICliCommand ;
44
+ if ( ! CommandProvider . TryGetCommand ( commandName , out Type ? commandType ) ) {
45
+ if ( Logger is null ) throw new Exception ( $ "Could not find command by name { commandName } ") ;
46
+ Logger . LogWarning ( "Could not find command by name {name}" , commandName ) ;
47
+ return ;
48
+ }
49
+
50
+ if ( ! TryCreateCommandInstance ( commandType , out ICliCommand ? command ) ) {
51
+ if ( Logger is null ) throw new Exception ( $ "Could not instantiate command with type { commandType . FullName } ") ;
52
+ Logger . LogWarning ( "Could not instantiate command with type {type}" , commandType . FullName ) ;
53
+ return ;
54
+
55
+ }
45
56
46
-
47
- if ( command is null ) throw new Exception ( "no Command found" ) ;
48
-
49
57
ParameterDictionary parameterDictionary = ParameterDictionary . FromString ( parameterInput ) ;
50
58
await command . StartExecution ( parameterDictionary , ct ) ;
51
59
}
60
+
61
+ private bool TryCreateCommandInstance ( Type commandType , [ NotNullWhen ( true ) ] out ICliCommand ? command ) {
62
+ try {
63
+ if ( ServiceProvider is null ) {
64
+ object ? directInstance = Activator . CreateInstance ( commandType ) ;
65
+ command = directInstance as ICliCommand ;
66
+ return command is not null ;
67
+ }
68
+
69
+ IServiceScope scope = ServiceProvider . Value . CreateScope ( ) ;
70
+ object diInstance = ActivatorUtilities . CreateInstance ( scope . ServiceProvider , commandType ) ;
71
+ command = diInstance as ICliCommand ;
72
+ return command is not null ;
73
+ }
74
+ catch ( Exception e ) {
75
+ // Throw if we cant log
76
+ if ( Logger is null ) throw ;
77
+ Logger . LogWarning ( e , "Failed to create command instance" ) ;
78
+ command = null ;
79
+ return false ;
80
+ }
81
+ }
52
82
}
0 commit comments