namespace Automancer; using System; using System.Linq; using System.Threading.Tasks; using Automancer.Common; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Spectre.Console.Cli; using Automancer.Commands; using System.Reflection; public abstract class Program { public static async Task Main(string[] args) { CommandApp? app = null; var host = Host.CreateDefaultBuilder(args) .ConfigureLogging(logging => { logging.ClearProviders(); logging.AddConsole(); logging.SetMinimumLevel(LogLevel.Information); }) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.SetBasePath(AppContext.BaseDirectory) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables(prefix: "AUTOMANCER_") .AddCommandLine(args); }) .ConfigureServices((context, services) => { var registry = new CommandRegistry(); services.AddSingleton(registry); LoadPluginAssemblies("plugins"); RegisterCommandModules(services); var registrar = new TypeRegistrar(services); app = new CommandApp(registrar); app.SetDefaultCommand(); var provider = services.BuildServiceProvider(); app.Configure(config => { config.SetApplicationName("automancer"); var modules = provider.GetServices(); var registry = provider.GetRequiredService(); foreach (var module in modules) { module.Configure(config, registry); } }); }) .Build(); return app != null ? await app.RunAsync(args) : 1; } private static void RegisterCommandModules(IServiceCollection services) { var moduleType = typeof(ICommandModule); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var moduleTypes = assemblies .SelectMany(a => { try { return a.GetTypes(); } catch { return []; } }) .Where(t => moduleType.IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract) .ToList(); foreach (var type in moduleTypes) { services.AddSingleton(type); services.AddSingleton(typeof(ICommandModule), type); } } private static void LoadPluginAssemblies(string pluginDirectory) { if (!Directory.Exists(pluginDirectory)) return; var dlls = Directory.GetFiles(pluginDirectory, "*.dll", SearchOption.AllDirectories); foreach (var dll in dlls) { try { var asm = Assembly.LoadFrom(dll); } catch (Exception ex) { Console.WriteLine($"[WARN] Failed to load plugin '{dll}': {ex.Message}"); } } } }