/// <summary> /// Boots the runtime within a timer. /// </summary> protected virtual IFactory Boot(IRegister register, DisposableTimer timer) { Composition composition = null; try { // Setup event listener UnattendedInstalled += CoreRuntime_UnattendedInstalled; // throws if not full-trust new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted).Demand(); // run handlers RuntimeOptions.DoRuntimeBoot(ProfilingLogger); // application caches var appCaches = GetAppCaches(); // database factory var databaseFactory = GetDatabaseFactory(); // configs var configs = GetConfigs(); // type loader var typeLoader = new TypeLoader(appCaches.RuntimeCache, configs.Global().LocalTempPath, ProfilingLogger); // runtime state // beware! must use '() => _factory.GetInstance<T>()' and NOT '_factory.GetInstance<T>' // as the second one captures the current value (null) and therefore fails _state = new RuntimeState(Logger, configs.Settings(), configs.Global(), new Lazy <IMainDom>(() => _factory.GetInstance <IMainDom>()), new Lazy <IServerRegistrar>(() => _factory.GetInstance <IServerRegistrar>())) { Level = RuntimeLevel.Boot }; // TODO: remove this in netcore, this is purely backwards compat hacks with the empty ctor if (MainDom == null) { MainDom = new MainDom(Logger, new MainDomSemaphoreLock(Logger)); } // create the composition composition = new Composition(register, typeLoader, ProfilingLogger, _state, configs); composition.RegisterEssentials(Logger, Profiler, ProfilingLogger, MainDom, appCaches, databaseFactory, typeLoader, _state); // run handlers RuntimeOptions.DoRuntimeEssentials(composition, appCaches, typeLoader, databaseFactory); // register runtime-level services // there should be none, really - this is here "just in case" Compose(composition); // acquire the main domain - if this fails then anything that should be registered with MainDom will not operate AcquireMainDom(MainDom); // determine our runtime level DetermineRuntimeLevel(databaseFactory, ProfilingLogger); // get composers, and compose var composerTypes = ResolveComposerTypes(typeLoader); IEnumerable <Attribute> enableDisableAttributes; using (ProfilingLogger.DebugDuration <CoreRuntime>("Scanning enable/disable composer attributes")) { enableDisableAttributes = typeLoader.GetAssemblyAttributes(typeof(EnableComposerAttribute), typeof(DisableComposerAttribute)); } var composers = new Composers(composition, composerTypes, enableDisableAttributes, ProfilingLogger); composers.Compose(); // create the factory _factory = Current.Factory = composition.CreateFactory(); // determines if unattended install is enabled and performs it if required DoUnattendedInstall(databaseFactory); // determine our runtime level (AFTER UNATTENDED INSTALL) // TODO: Feels kinda weird to call this again DetermineRuntimeLevel(databaseFactory, ProfilingLogger); // if level is Run and reason is UpgradeMigrations, that means we need to perform an unattended upgrade if (_state.Reason == RuntimeLevelReason.UpgradeMigrations && _state.Level == RuntimeLevel.Run) { // do the upgrade DoUnattendedUpgrade(_factory.GetInstance <DatabaseBuilder>()); // upgrade is done, set reason to Run _state.Reason = RuntimeLevelReason.Run; } // create & initialize the components _components = _factory.GetInstance <ComponentCollection>(); _components.Initialize(); } catch (Exception e) { var bfe = e as BootFailedException ?? new BootFailedException("Boot failed.", e); if (_state != null) { _state.Level = RuntimeLevel.BootFailed; _state.BootFailedException = bfe; } timer?.Fail(exception: bfe); // be sure to log the exception - even if we repeat ourselves // if something goes wrong above, we may end up with no factory // meaning nothing can get the runtime state, etc - so let's try // to make sure we have a factory if (_factory == null) { try { _factory = Current.Factory = composition?.CreateFactory(); } catch { // In this case we are basically dead, we do not have a factory but we need // to report on the state so we need to manually set that, this is the only time // we ever do this. Current.RuntimeState = _state; } } Debugger.Break(); // throwing here can cause w3wp to hard-crash and we want to avoid it. // instead, we're logging the exception and setting level to BootFailed. // various parts of Umbraco such as UmbracoModule and UmbracoDefaultOwinStartup // understand this and will nullify themselves, while UmbracoModule will // throw a BootFailedException for every requests. } return(_factory); }