Exemplo n.º 1
0
        /// <summary>
        ///   Runs this server
        /// </summary>
        public void Run()
        {
            Condition.Requires(Kernel, "kernel").IsNull("Expected server to not be configured yet");

            // Install logging
            GlobalLogger = ConfigureGlobalLogger();
            Condition.Requires(GlobalLogger, "GlobalLogger").IsNotNull();
            AppDomain.CurrentDomain.UnhandledException +=
                (obj, args) => GlobalLogger.Error(args.ExceptionObject as Exception, "Unhandled Exception");
            Log = GlobalLogger.ForContext(GetType());

            // Load all modules
            Log.Information("Assembling module list");
            var modules = new List <AbstractModule>();

            GetAllRegisteredModules(modules);

            // Parse Flags, and set static flags before initializing any module. Has to happen
            // after the module list is generated so that all required assemblies are loaded.
            FlagParser = new FlagParser(Log.ForContext <FlagParser>());
            FlagParser.ParseCommandLineArguments(Environment.GetCommandLineArgs().Skip(1));

            // Initialize every module
            Log.Information("Registering Modules:");
            foreach (var module in modules)
            {
                Log.Information("  {module}", module);

                // Pre-inject the logger so that it is always available (even before the kernel is initialized)
                module.Logger = GlobalLogger.ForContext(module.GetType());

                // Same goes for flags
                FlagParser.InjectFlags(module);
            }

            // Initialize Kernel
            Log.Information("Initializing Injection Kernel");
            Kernel = new StandardKernel(modules.ToArray());
            Kernel.Settings.InjectNonPublic = true;
            ConfigureBindings();

            // Initialize modules
            Log.Information("Injecting module members");
            foreach (var module in modules)
            {
                // Lazily initialize module injections
                Kernel.Inject(module);
            }

            // Run all server tasks
            var taskModules = modules.OfType <AbstractTaskModule>().ToArray();

            Log.Information("==============================================================");
            Log.Information("Starting Tasks: {taskModules}", taskModules);
            var tasks = taskModules.Select(x => Task.Run(async() => {
                try {
                    await x.Run();
                } catch (Exception ex) {
                    Log.Error(ex, "Task execution failed");
                }
            })).ToArray();

            // Wait for all tasks to finish
            Task.WaitAll(tasks);
            Log.Information("All tasks have finished execution");
        }