public async Task StartAsync(CancellationToken cancellationToken) { await interceptor.OnBatchEngineBegin(); // raise after all event registered appLifetime.ApplicationStarted.Register(async state => { var self = (BatchEngineService)state; try { var engine = new BatchEngine(self.logger, self.provider, self.interceptor, self.cancellationTokenSource.Token); if (self.methodInfo != null) { self.runningTask = engine.RunAsync(self.type, self.methodInfo, self.args); } else { self.runningTask = engine.RunAsync(self.type, self.args); } await self.runningTask; self.runningTask = null; } finally { self.appLifetime.StopApplication(); } }, this); }
public async Task RunAsync(Type type, string[] args) { logger.LogTrace("BatchEngine.Run Start"); int argsOffset = 0; MethodInfo method = null; var ctx = new BatchContext(args, DateTime.UtcNow, cancellationToken, logger); try { await interceptor.OnBatchRunBeginAsync(ctx); if (type == typeof(void)) { await SetFailAsync(ctx, "Type or method does not found on this Program. args: " + string.Join(" ", args)); return; } var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (methods.Length == 0) { await SetFailAsync(ctx, "Method can not select. T of Run/UseBatchEngine<T> have to be contain single method or command. Type:" + type.FullName); return; } MethodInfo helpMethod = null; foreach (var item in methods) { var command = item.GetCustomAttribute <CommandAttribute>(); if (command != null) { if (args.Length > 0 && command.EqualsAny(args[0])) { // command's priority is first method = item; argsOffset = 1; goto RUN; } else { if (command.EqualsAny("help")) { helpMethod = item; } } } else { if (method != null) { await SetFailAsync(ctx, "Found two public methods(wihtout command). Type:" + type.FullName + " Method:" + method.Name + " and " + item.Name); return; } method = item; // found single public(non-command) method. } } if (method != null) { goto RUN; } // completely not found, invalid command name show help. if (helpMethod != null) { method = helpMethod; goto RUN; } else { Console.WriteLine(BatchEngine.BuildHelpParameter(methods)); return; } } catch (Exception ex) { await SetFailAsync(ctx, "Fail to get method. Type:" + type.FullName, ex); return; } RUN: await RunCore(ctx, type, method, args, argsOffset); }
public static IHostBuilder UseBatchEngine <T>(this IHostBuilder hostBuilder, string[] args, IBatchInterceptor interceptor = null) where T : BatchBase { var method = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); var defaultMethod = method.FirstOrDefault(x => x.GetCustomAttribute <CommandAttribute>() == null); var hasList = method.Any(x => x.GetCustomAttribute <CommandAttribute>()?.EqualsAny(ListCommand) ?? false); var hasHelp = method.Any(x => x.GetCustomAttribute <CommandAttribute>()?.EqualsAny(HelpCommand) ?? false); if (args.Length == 0) { if (defaultMethod == null || (defaultMethod.GetParameters().Length != 0 && !defaultMethod.GetParameters().All(x => x.HasDefaultValue))) { if (!hasHelp) { Console.WriteLine(BatchEngine.BuildHelpParameter(method)); hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <IHostedService, EmptyHostedService>(); }); return(hostBuilder); } else { // override default Help args = new string[] { "help" }; } } } if (!hasList && args.Length == 1 && args[0].Equals(ListCommand, StringComparison.OrdinalIgnoreCase)) { ShowMethodList(); hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <IHostedService, EmptyHostedService>(); }); return(hostBuilder); } if (!hasHelp && args.Length == 1 && args[0].Equals(HelpCommand, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine(BatchEngine.BuildHelpParameter(method)); hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <IHostedService, EmptyHostedService>(); }); return(hostBuilder); } hostBuilder = hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <string[]>(args); services.AddSingleton <Type>(typeof(T)); services.AddSingleton <IHostedService, BatchEngineService>(); services.AddSingleton <IBatchInterceptor>(interceptor ?? NullBatchInterceptor.Default); services.AddTransient <T>(); }); return(hostBuilder.UseConsoleLifetime()); }
public static IHostBuilder UseBatchEngine(this IHostBuilder hostBuilder, string[] args, IBatchInterceptor interceptor = null) { if (args.Length == 0 || (args.Length == 1 && args[0].Equals(ListCommand, StringComparison.OrdinalIgnoreCase))) { ShowMethodList(); hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <IHostedService, EmptyHostedService>(); }); return(hostBuilder); } if (args.Length == 2 && args[0].Equals(HelpCommand, StringComparison.OrdinalIgnoreCase)) { var(t, mi) = GetTypeFromAssemblies(args[1]); if (mi != null) { Console.WriteLine(BatchEngine.BuildHelpParameter(new[] { mi })); } else { Console.WriteLine("Method not found , please check \"list\" command."); } hostBuilder.ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <IHostedService, EmptyHostedService>(); }); return(hostBuilder); } Type type = null; MethodInfo methodInfo = null; if (args.Length >= 1) { (type, methodInfo) = GetTypeFromAssemblies(args[0]); } hostBuilder = hostBuilder .ConfigureServices(services => { services.AddOptions <ConsoleLifetimeOptions>().Configure(x => x.SuppressStatusMessages = true); services.AddSingleton <string[]>(args); services.AddSingleton <IHostedService, BatchEngineService>(); services.AddSingleton <IBatchInterceptor>(interceptor ?? NullBatchInterceptor.Default); if (type != null) { services.AddSingleton <Type>(type); services.AddTransient(type); } else { services.AddSingleton <Type>(typeof(void)); } if (methodInfo != null) { services.AddSingleton <MethodInfo>(methodInfo); } }); return(hostBuilder.UseConsoleLifetime()); }