public async Task ApplyChanges() { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Applying changes for for tenant '{TenantName}'", _settings.Name); } var loadedFeatures = await _extensionManager.LoadFeaturesAsync(); var shellState = await _stateManager.GetShellStateAsync(); // merge feature state into ordered list var loadedEntries = loadedFeatures .Select(fe => new { Feature = fe, FeatureDescriptor = fe.FeatureInfo, FeatureState = shellState.Features.FirstOrDefault(s => s.Id == fe.FeatureInfo.Id), }) .Where(entry => entry.FeatureState != null) .ToArray(); // find feature state that is beyond what's currently available from modules var additionalState = shellState.Features.Except(loadedEntries.Select(entry => entry.FeatureState)); // create additional stub entries for the sake of firing state change events on missing features var allEntries = loadedEntries.Concat(additionalState.Select(featureState => { var featureDescriptor = new InternalFeatureInfo( featureState.Id, new InternalExtensionInfo(featureState.Id) ); return(new { Feature = (FeatureEntry) new NonCompiledFeatureEntry(featureDescriptor), FeatureDescriptor = (IFeatureInfo)featureDescriptor, FeatureState = featureState }); })).ToArray(); // lower enabled states in reverse order foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.EnableState == ShellFeatureState.State.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Disabling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Disabling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, ShellFeatureState.State.Down); _featureEventHandlers.Invoke(x => x.Disabled(entry.Feature.FeatureInfo), Logger); } // lower installed states in reverse order foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.InstallState == ShellFeatureState.State.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Uninstalling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Uninstalling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, ShellFeatureState.State.Down); _featureEventHandlers.Invoke(x => x.Uninstalled(entry.Feature.FeatureInfo), Logger); } // raise install and enabled states in order foreach (var entry in allEntries.Where(entry => IsRising(entry.FeatureState))) { if (entry.FeatureState.InstallState == ShellFeatureState.State.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Installing feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Installing(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, ShellFeatureState.State.Up); _featureEventHandlers.Invoke(x => x.Installed(entry.Feature.FeatureInfo), Logger); } if (entry.FeatureState.EnableState == ShellFeatureState.State.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Enabling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Enabling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, ShellFeatureState.State.Up); _featureEventHandlers.Invoke(x => x.Enabled(entry.Feature.FeatureInfo), Logger); } } }
public async Task ApplyChanges() { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Applying changes for for shell '{0}'", _settings.Name); } var shellState = await _stateManager.GetShellStateAsync(); // start with description of all declared features in order - order preserved with all merging var orderedFeatureDescriptors = _extensionManager.GetExtensions().Features; // merge feature state into ordered list var orderedFeatureDescriptorsAndStates = orderedFeatureDescriptors .Select(featureInfo => new { FeatureDescriptor = featureInfo, FeatureState = shellState.Features.FirstOrDefault(s => s.Id == featureInfo.Id), }) .Where(entry => entry.FeatureState != null) .ToArray(); // get loaded feature information var loadedFeatures = await Task.WhenAll(orderedFeatureDescriptorsAndStates .Select(x => _extensionManager.LoadFeatureAsync(x.FeatureDescriptor)) .ToArray()); // merge loaded feature information into ordered list var loadedEntries = orderedFeatureDescriptorsAndStates.Select( entry => new { Feature = loadedFeatures.SingleOrDefault(f => f.FeatureInfo == entry.FeatureDescriptor) ?? new NonCompiledFeatureEntry(entry.FeatureDescriptor), entry.FeatureDescriptor, entry.FeatureState, }).ToList(); // find feature state that is beyond what's currently available from modules var additionalState = shellState.Features.Except(loadedEntries.Select(entry => entry.FeatureState)); // create additional stub entries for the sake of firing state change events on missing features var allEntries = loadedEntries.Concat(additionalState.Select(featureState => { var featureDescriptor = new InternalFeatureInfo( featureState.Id, new InternalExtensionInfo(featureState.Id) ); return(new { Feature = (FeatureEntry) new NonCompiledFeatureEntry(featureDescriptor), FeatureDescriptor = (IFeatureInfo)featureDescriptor, FeatureState = featureState }); })).ToArray(); // lower enabled states in reverse order foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.EnableState == ShellFeatureState.State.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Disabling feature '{0}'", entry.Feature.FeatureInfo.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Disabling(entry.Feature.FeatureInfo)); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, ShellFeatureState.State.Down); _eventBus.Notify <IFeatureEventHandler>(x => x.Disabled(entry.Feature.FeatureInfo)); } // lower installed states in reverse order foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.InstallState == ShellFeatureState.State.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Uninstalling feature '{0}'", entry.Feature.FeatureInfo.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Uninstalling(entry.Feature.FeatureInfo)); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, ShellFeatureState.State.Down); _eventBus.Notify <IFeatureEventHandler>(x => x.Uninstalled(entry.Feature.FeatureInfo)); } // raise install and enabled states in order foreach (var entry in allEntries.Where(entry => IsRising(entry.FeatureState))) { if (entry.FeatureState.InstallState == ShellFeatureState.State.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Installing feature '{0}'", entry.Feature.FeatureInfo.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Installing(entry.Feature.FeatureInfo)); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, ShellFeatureState.State.Up); _eventBus.Notify <IFeatureEventHandler>(x => x.Installed(entry.Feature.FeatureInfo)); } if (entry.FeatureState.EnableState == ShellFeatureState.State.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Enabling feature '{0}'", entry.Feature.FeatureInfo.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Enabling(entry.Feature.FeatureInfo)); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, ShellFeatureState.State.Up); _eventBus.Notify <IFeatureEventHandler>(x => x.Enabled(entry.Feature.FeatureInfo)); } } }
public async Task ApplyChanges() { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Applying changes for for tenant '{TenantName}'", _settings.Name); } var loadedFeatures = await _pluginManager.LoadFeaturesAsync(); var engineState = await _stateManager.GetEngineStateAsync(); var loadedEntries = loadedFeatures .Select(fe => new { Feature = fe, FeatureDescriptor = fe.FeatureInfo, FeatureState = engineState.Features.FirstOrDefault(s => s.Id == fe.FeatureInfo.Id), }) .Where(entry => entry.FeatureState != null) .ToArray(); var additionalState = engineState.Features.Except(loadedEntries.Select(entry => entry.FeatureState)); var allEntries = loadedEntries.Concat(additionalState.Select(featureState => { var featureDescriptor = new InternalFeatureInfo( featureState.Id, new InternalPluginInfo(featureState.Id) ); return(new { Feature = (FeatureEntry) new NonCompiledFeatureEntry(featureDescriptor), FeatureDescriptor = (IFeatureInfo)featureDescriptor, FeatureState = featureState }); })).ToArray(); foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.EnableState == EngineFeatureState.States.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Disabling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Disabling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, EngineFeatureState.States.Down); _featureEventHandlers.Invoke(x => x.Disabled(entry.Feature.FeatureInfo), Logger); } foreach (var entry in allEntries.Reverse().Where(entry => entry.FeatureState.InstallState == EngineFeatureState.States.Falling)) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Uninstalling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Uninstalling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, EngineFeatureState.States.Down); _featureEventHandlers.Invoke(x => x.Uninstalled(entry.Feature.FeatureInfo), Logger); } foreach (var entry in allEntries.Where(entry => IsRising(entry.FeatureState))) { if (entry.FeatureState.InstallState == EngineFeatureState.States.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Installing feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Installing(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateInstalledStateAsync(entry.FeatureState, EngineFeatureState.States.Up); _featureEventHandlers.Invoke(x => x.Installed(entry.Feature.FeatureInfo), Logger); } if (entry.FeatureState.EnableState == EngineFeatureState.States.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Enabling feature '{FeatureName}'", entry.Feature.FeatureInfo.Id); } _featureEventHandlers.Invoke(x => x.Enabling(entry.Feature.FeatureInfo), Logger); await _stateManager.UpdateEnabledStateAsync(entry.FeatureState, EngineFeatureState.States.Up); _featureEventHandlers.Invoke(x => x.Enabled(entry.Feature.FeatureInfo), Logger); } } }