/// <summary> /// Resolves <see cref="DirectiveSchema"/>. /// </summary> public static DirectiveSchema Resolve(Type type, IReadOnlyList <Type> modeTypes) { if (!KnownTypesHelpers.IsDirectiveType(type)) { throw DirectiveResolverExceptions.InvalidDirectiveType(type); } DirectiveAttribute attribute = type.GetCustomAttribute <DirectiveAttribute>() !; if (modeTypes is not null) { if (attribute.SupportedModes is not null && attribute.SupportedModes.Except(modeTypes).Any()) { throw DirectiveResolverExceptions.InvalidSupportedModesInDirective(type, attribute); } if (attribute.ExcludedModes is not null && attribute.ExcludedModes.Except(modeTypes).Any()) { throw DirectiveResolverExceptions.InvalidExcludedModesInDirective(type, attribute); } } return(new DirectiveSchema( type, attribute.Name, attribute.Description, attribute.SupportedModes, attribute.ExcludedModes )); }
/// <summary> /// Resolves <see cref="CommandSchema"/>. /// </summary> public static CommandSchema Resolve(Type type, IReadOnlyList <Type>?modeTypes) { if (!KnownTypesHelpers.IsCommandType(type)) { throw CommandResolverExceptions.InvalidCommandType(type); } CommandAttribute attribute = type.GetCustomAttribute <CommandAttribute>() !; if (modeTypes != null) { if (attribute.SupportedModes != null && attribute.SupportedModes.Except(modeTypes).Any()) { throw CommandResolverExceptions.InvalidSupportedModesInCommand(type, attribute); } if (attribute.ExcludedModes != null && attribute.ExcludedModes.Except(modeTypes).Any()) { throw CommandResolverExceptions.InvalidExcludedModesInCommand(type, attribute); } } string?name = attribute.Name; CommandOptionSchema[] builtInOptions = string.IsNullOrWhiteSpace(name) ? new[] { CommandOptionSchema.HelpOption, CommandOptionSchema.VersionOption } : new[] { CommandOptionSchema.HelpOption }; CommandParameterSchema?[] parameters = type.GetProperties() .Select(CommandParameterSchemaResolver.TryResolve) .Where(p => p != null) .OrderBy(p => p !.Order) .ToArray(); CommandOptionSchema?[] options = type.GetProperties() .Select(CommandOptionSchemaResolver.TryResolve) .Where(o => o != null) .Concat(builtInOptions) .ToArray(); CommandSchema command = new CommandSchema( type, name, attribute.Description, attribute.Manual, attribute.SupportedModes, attribute.ExcludedModes, parameters !, options ! ); ValidateParameters(command); ValidateOptions(command); return(command); }
/// <summary> /// Registers a CLI mode. Only one mode can be registered as startup mode. /// If no mode was registered or none of the registered modes was marked as startup, <see cref="DirectMode"/> will be registered. /// /// Do not call RegisterMode directly from builder, instead call UseXMode method, e.g. UseDirectMode(). /// </summary> public CliApplicationBuilder RegisterMode(Type modeType, bool asStartup = false) { Type cliMode = modeType; _modeTypes.Add(cliMode); if (!KnownTypesHelpers.IsCliModeType(modeType)) { throw new ArgumentException($"Invalid CLI mode type '{modeType}'.", nameof(modeType)); } _configureServicesActions.Add(services => { services.TryAddSingleton(cliMode); services.AddSingleton(typeof(ICliMode), (IServiceProvider sp) => sp.GetRequiredService(cliMode)); }); if (asStartup) { _startupMode = _startupMode is null ? cliMode : throw new ArgumentException($"Only one mode can be registered as startup mode.", nameof(asStartup)); } return(this); }