예제 #1
0
        /// <summary>
        /// 启动应用程序,并返回 <see cref="App"/> 的一个实例。<br />
        /// 执行该方法的流程:<br />
        /// 10. <see cref="AppSetup"/> 将 <see cref="CoreAppModule"/> 和 参数提供的 <see cref="IAppModule"/> 作为根模块扫描所有参与启动的 <see cref="IAppModule"/> 类型 <br />
        /// 11. 根据收集到的类型所在的程序集,注册所有标记了 <see cref="ToolAttribute"/> 的类型到 <see cref="Tools"/> 属性中 <br />
        /// 15. 调用所有 <see cref="IAppModule"/> 上的 <see cref="AppModulePrepairAttribute.Prepair(AppModulePrepareArguments)"/> 方法。<br />
        /// 20. 触发 <see cref="IAppSetupPlugin.OnAllAppModuleTypeCollected(AppSetup, OnAllAppModuleTypeCollectedArguments)"/> 事件 <br />
        /// 30. 调用 <see cref="Use(IAppModule, IAppModule)"/>,参数是 null 和 <see cref="CoreAppModule"/> 用于加载 AppStarter 库中的各种组件 <br />
        /// 40. 调用 <see cref="Use(IAppModule, IAppModule)"/>,参数是 null 和 appModule 用于加载指定的 <see cref="IAppModule"/> 中的各种组件 <br />
        /// 50. 触发 <see cref="AllModulesLoaded"/> 事件 <br />
        /// 60. 遍历所有 <see cref="IAppContainerBuilder"/> 分别调用 <see cref="IAppContainerBuilder.Prepare(AppSetup)"/> 和 <see cref="IAppContainerBuilder.Build(AppSetup)"/> 方法 <br />
        /// 70. 生成 <see cref="App"/> 实例 <br />
        /// 80. 调用所有 <see cref="IAppContainer.OnAppStarted(App)"/> 方法
        /// </summary>
        /// <param name="appModule"></param>
        /// <returns></returns>
        public App Start(IAppModule appModule)
        {
            IEnumerable <IAppModule> rootModules = new IAppModule[]
            {
                new CoreAppModule(),
                appModule
            };

            this.CollectAllAppModuleType(rootModules);
            this.Tools.InjectFields(this);

            rootModules.ForEach(module =>
            {
                this.Use(null, module);
            });

            this.AllModulesLoaded?.Invoke(this, EventArgs.Empty);
            IEnumerable <IAppContainer> appContainers
                = this.appContainerBuilders
                  .ForEach(x => x.Prepare(this))
                  .Select(x => x.Build(this))
                  .ToList();
            App app = new App(appContainers, this.AppContext);

            appContainers.ForEach(x => x.OnAppStarted(app));
            using (var work = app.BeginWork("OnAppStart"))
            {
                work.PublishEvent(new AppStartingEvent(this, app));
                work.PublishEvent(new AppStartedEvent(this, app));
            }
            return(app);
        }