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);
        }
Beispiel #2
0
        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());
        }