public void Uninstall(string packageId, string applicationPath) { var extensionToUninstall = _extensionManager.AvailableExtensions() .FirstOrDefault(extension => PackageBuilder.BuildPackageId(extension.Id, extension.ExtensionType) == packageId); if (extensionToUninstall == null) { throw new OrchardException(T("There is no extension that has the package ID \"{0}\".", packageId)); } var featureIdsToUninstall = extensionToUninstall.Features.Select(feature => feature.Id); var shellState = _shellStateManager.GetShellState(); var featureStates = shellState.Features.Where(featureState => featureIdsToUninstall.Contains(featureState.Name)); // This means that no feature from this extension wasn enabled yet, can be uninstalled directly. if (!featureStates.Any()) { _packageUninstallHandler.QueuePackageUninstall(packageId); } else { _featureManager.DisableFeatures(extensionToUninstall.Features.Select(feature => feature.Id), true); // Installed state can't be deduced from the shell state changes like for enabled state, so have to // set that explicitly. foreach (var featureState in featureStates) { _shellStateManager.UpdateInstalledState(featureState, Environment.State.Models.ShellFeatureState.State.Falling); } } }
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) { // deduce and apply state changes involved var shellState = _stateManager.GetShellState(); foreach (var feature in descriptor.Features) { var featureName = feature.Name; var featureState = shellState.Features.SingleOrDefault(f => f.Name == featureName); if (featureState == null) { featureState = new ShellFeatureState { Name = featureName }; shellState.Features = shellState.Features.Concat(new[] { featureState }); } if (!featureState.IsInstalled) { _stateManager.UpdateInstalledState(featureState, ShellFeatureState.State.Rising); } if (!featureState.IsEnabled) { _stateManager.UpdateEnabledState(featureState, ShellFeatureState.State.Rising); } } foreach (var featureState in shellState.Features) { var featureName = featureState.Name; if (descriptor.Features.Any(f => f.Name == featureName)) { continue; } if (!featureState.IsDisabled) { _stateManager.UpdateEnabledState(featureState, ShellFeatureState.State.Falling); } } FireApplyChangesIfNeeded(); }
public void ApplyChanges() { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Applying changes for for shell '{0}'", _settings.Name); } var shellState = _stateManager.GetShellStateAsync().Result; // start with description of all declared features in order - order preserved with all merging var orderedFeatureDescriptors = _extensionManager.AvailableFeatures(); // merge feature state into ordered list var orderedFeatureDescriptorsAndStates = orderedFeatureDescriptors .Select(featureDescriptor => new { FeatureDescriptor = featureDescriptor, FeatureState = shellState.Features.FirstOrDefault(s => s.Name == featureDescriptor.Id), }) .Where(entry => entry.FeatureState != null) .ToArray(); // get loaded feature information var loadedFeatures = _extensionManager.LoadFeatures(orderedFeatureDescriptorsAndStates.Select(entry => entry.FeatureDescriptor)).ToArray(); // merge loaded feature information into ordered list var loadedEntries = orderedFeatureDescriptorsAndStates.Select( entry => new { Feature = loadedFeatures.SingleOrDefault(f => f.Descriptor == entry.FeatureDescriptor) ?? new Feature { Descriptor = entry.FeatureDescriptor, ExportedTypes = Enumerable.Empty <Type>() }, 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 FeatureDescriptor { Id = featureState.Name, Extension = new ExtensionDescriptor { Id = featureState.Name } }; return(new { Feature = new Feature { Descriptor = featureDescriptor, ExportedTypes = Enumerable.Empty <Type>(), }, FeatureDescriptor = 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.Descriptor.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Disabling(entry.Feature)); _stateManager.UpdateEnabledState(entry.FeatureState, ShellFeatureState.State.Down); _eventBus.Notify <IFeatureEventHandler>(x => x.Disabled(entry.Feature)); } // 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.Descriptor.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Uninstalling(entry.Feature)); _stateManager.UpdateInstalledState(entry.FeatureState, ShellFeatureState.State.Down); _eventBus.Notify <IFeatureEventHandler>(x => x.Uninstalled(entry.Feature)); } // 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.Descriptor.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Installing(entry.Feature)); _stateManager.UpdateInstalledState(entry.FeatureState, ShellFeatureState.State.Up); _eventBus.Notify <IFeatureEventHandler>(x => x.Installed(entry.Feature)); } if (entry.FeatureState.EnableState == ShellFeatureState.State.Rising) { if (Logger.IsEnabled(LogLevel.Information)) { Logger.LogInformation("Enabling feature '{0}'", entry.Feature.Descriptor.Id); } _eventBus.Notify <IFeatureEventHandler>(x => x.Enabling(entry.Feature)); _stateManager.UpdateEnabledState(entry.FeatureState, ShellFeatureState.State.Up); _eventBus.Notify <IFeatureEventHandler>(x => x.Enabled(entry.Feature)); } } }