Ejemplo n.º 1
0
        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();
        }
Ejemplo n.º 2
0
        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));
                }
            }
        }