Beispiel #1
0
        internal void UpdateFrom( IConfigurationSolver solver )
        {
            // 1 - Removes existing items from live info that do not exist anymore in the new running context.
            //     This raises Collection "item removed" events.
            //
            _services.RemoveWhereAndReturnsRemoved( s => solver.FindService( s.ServiceInfo.ServiceFullName ) == null ).Count();
            _plugins.RemoveWhereAndReturnsRemoved( p => solver.FindPlugin( p.PluginInfo.PluginFullName ) == null ).Count();

            DelayedPropertyNotification notifier = new DelayedPropertyNotification();

            // 2 - Builds two lists of new Services and new Plugins and for already existing ones,
            //     updates them with the new information.
            //     This update does not trigger any ProprtyChanged events and consider only
            //     direct properties of the object.
            //     Changes to linked items (such as a Generalization reference for instance will be
            //     done later thanks to their Bind method.
            //
            List<LiveServiceInfo> servicesToAdd = new List<LiveServiceInfo>();
            foreach( var s in solver.AllServices )
            {
                LiveServiceInfo ls = _services.GetByKey( s.ServiceInfo.ServiceFullName );
                if( ls == null ) servicesToAdd.Add( new LiveServiceInfo( s, _engine ) );
                else ls.UpdateFrom( s, notifier );
            }

            List<LivePluginInfo> pluginsToAdd = new List<LivePluginInfo>();
            foreach( var p in solver.AllPlugins )
            {
                LivePluginInfo lp = _plugins.GetByKey( p.PluginInfo.PluginFullName );
                if( lp == null ) pluginsToAdd.Add( new LivePluginInfo( p, _engine ) );
                else lp.UpdateFrom( p, notifier );
            }

            // 3 - Intrinsic properties have been updated. We now consider the properties that reference other items.
            //
            Func<string,LiveServiceInfo> serviceFinder = name => _services.GetByKey( name ) ?? servicesToAdd.First( ls => ls.ServiceInfo.ServiceFullName == name );
            Func<string,LivePluginInfo> pluginFinder = id => _plugins.GetByKey( id ) ?? pluginsToAdd.First( lp => lp.PluginInfo.PluginFullName == id );

            using( notifier.SilentMode() )
            {
                foreach( var ls in servicesToAdd ) ls.Bind( solver.FindExistingService( ls.ServiceInfo.ServiceFullName ), serviceFinder, pluginFinder, notifier );
            }
            foreach( var ls in _services ) ls.Bind( solver.FindExistingService( ls.ServiceInfo.ServiceFullName ), serviceFinder, pluginFinder, notifier );

            using( notifier.SilentMode() )
            {
                foreach( var lp in pluginsToAdd ) lp.Bind( solver.FindExistingPlugin( lp.PluginInfo.PluginFullName ), serviceFinder, notifier );
            }
            foreach( var lp in _plugins ) lp.Bind( solver.FindExistingPlugin( lp.PluginInfo.PluginFullName ), serviceFinder, notifier );

            // 4 - It is time to add the new comers: this raises Collection changed "item added" events.
            foreach( var ls in servicesToAdd ) _services.Add( ls );
            foreach( var lp in pluginsToAdd ) _plugins.Add( lp );

            // 5 - Raises all PropertyChanged events for all objects.
            notifier.RaiseEvents();
        }
Beispiel #2
0
        public IEnumerable <ServiceData> GetIncludedServices(StartDependencyImpact impact, bool forRunnableStatus)
        {
            if (_runningIncludedServices == null)
            {
                var running = Service != null ? new HashSet <ServiceData>(Service.InheritedServicesWithThis) : new HashSet <ServiceData>();
                foreach (var sRef in PluginInfo.ServiceReferences)
                {
                    if (sRef.Requirement == DependencyRequirement.Running)
                    {
                        running.Add(_solver.FindExistingService(sRef.Reference.ServiceFullName));
                    }
                }
                _runningIncludedServices = running.ToReadOnlyList();
                bool newRunnableAdded = false;
                foreach (var sRef in PluginInfo.ServiceReferences)
                {
                    if (sRef.Requirement == DependencyRequirement.Runnable)
                    {
                        newRunnableAdded |= running.Add(_solver.FindExistingService(sRef.Reference.ServiceFullName));
                    }
                }
                _runnableIncludedServices = newRunnableAdded ? running.ToReadOnlyList() : _runningIncludedServices;
            }

            if (impact == StartDependencyImpact.Minimal)
            {
                return(forRunnableStatus ? _runnableIncludedServices : _runningIncludedServices);
            }

            if (_inclServices == null)
            {
                _inclServices = new IReadOnlyList <ServiceData> [8];
            }
            int iImpact = (int)impact;

            if (impact > StartDependencyImpact.Minimal)
            {
                --impact;
            }
            if (forRunnableStatus)
            {
                iImpact *= 2;
            }
            --iImpact;

            IReadOnlyList <ServiceData> i = _inclServices[iImpact];

            if (i == null)
            {
                var  baseSet  = forRunnableStatus ? _runnableIncludedServices : _runningIncludedServices;
                var  incl     = new HashSet <ServiceData>(baseSet);
                bool newAdded = false;
                foreach (var sRef in PluginInfo.ServiceReferences)
                {
                    ServiceData sr = _solver.FindExistingService(sRef.Reference.ServiceFullName);
                    switch (sRef.Requirement)
                    {
                    case DependencyRequirement.RunnableRecommended:
                    {
                        if (impact >= StartDependencyImpact.StartRecommended)
                        {
                            newAdded |= incl.Add(sr);
                        }
                        break;
                    }

                    case DependencyRequirement.Runnable:
                    {
                        if (impact == StartDependencyImpact.FullStart)
                        {
                            newAdded |= incl.Add(sr);
                        }
                        break;
                    }

                    case DependencyRequirement.OptionalRecommended:
                    {
                        if (impact >= StartDependencyImpact.StartRecommended)
                        {
                            newAdded |= incl.Add(sr);
                        }
                        break;
                    }

                    case DependencyRequirement.Optional:
                    {
                        if (impact == StartDependencyImpact.FullStart)
                        {
                            newAdded |= incl.Add(sr);
                        }
                        break;
                    }
                    }
                }
                i = _inclServices[iImpact] = newAdded ? incl.ToReadOnlyList() : baseSet;
            }
            return(i);
        }
Beispiel #3
0
        internal void UpdateFrom(IConfigurationSolver solver)
        {
            // 1 - Removes existing items from live info that do not exist anymore in the new running context.
            //     This raises Collection "item removed" events.
            //
            _services.RemoveWhereAndReturnsRemoved(s => solver.FindService(s.ServiceInfo.ServiceFullName) == null).Count();
            _plugins.RemoveWhereAndReturnsRemoved(p => solver.FindPlugin(p.PluginInfo.PluginFullName) == null).Count();

            DelayedPropertyNotification notifier = new DelayedPropertyNotification();

            // 2 - Builds two lists of new Services and new Plugins and for already existing ones,
            //     updates them with the new information.
            //     This update does not trigger any ProprtyChanged events and consider only
            //     direct properties of the object.
            //     Changes to linked items (such as a Generalization reference for instance will be
            //     done later thanks to their Bind method.
            //
            List <LiveServiceInfo> servicesToAdd = new List <LiveServiceInfo>();

            foreach (var s in solver.AllServices)
            {
                LiveServiceInfo ls = _services.GetByKey(s.ServiceInfo.ServiceFullName);
                if (ls == null)
                {
                    servicesToAdd.Add(new LiveServiceInfo(s, _engine));
                }
                else
                {
                    ls.UpdateFrom(s, notifier);
                }
            }

            List <LivePluginInfo> pluginsToAdd = new List <LivePluginInfo>();

            foreach (var p in solver.AllPlugins)
            {
                LivePluginInfo lp = _plugins.GetByKey(p.PluginInfo.PluginFullName);
                if (lp == null)
                {
                    pluginsToAdd.Add(new LivePluginInfo(p, _engine));
                }
                else
                {
                    lp.UpdateFrom(p, notifier);
                }
            }

            // 3 - Intrinsic properties have been updated. We now consider the properties that reference other items.
            //
            Func <string, LiveServiceInfo> serviceFinder = name => _services.GetByKey(name) ?? servicesToAdd.First(ls => ls.ServiceInfo.ServiceFullName == name);
            Func <string, LivePluginInfo>  pluginFinder  = id => _plugins.GetByKey(id) ?? pluginsToAdd.First(lp => lp.PluginInfo.PluginFullName == id);

            using (notifier.SilentMode())
            {
                foreach (var ls in servicesToAdd)
                {
                    ls.Bind(solver.FindExistingService(ls.ServiceInfo.ServiceFullName), serviceFinder, pluginFinder, notifier);
                }
            }
            foreach (var ls in _services)
            {
                ls.Bind(solver.FindExistingService(ls.ServiceInfo.ServiceFullName), serviceFinder, pluginFinder, notifier);
            }

            using (notifier.SilentMode())
            {
                foreach (var lp in pluginsToAdd)
                {
                    lp.Bind(solver.FindExistingPlugin(lp.PluginInfo.PluginFullName), serviceFinder, notifier);
                }
            }
            foreach (var lp in _plugins)
            {
                lp.Bind(solver.FindExistingPlugin(lp.PluginInfo.PluginFullName), serviceFinder, notifier);
            }

            // 4 - It is time to add the new comers: this raises Collection changed "item added" events.
            foreach (var ls in servicesToAdd)
            {
                _services.Add(ls);
            }
            foreach (var lp in pluginsToAdd)
            {
                _plugins.Add(lp);
            }

            // 5 - Raises all PropertyChanged events for all objects.
            notifier.RaiseEvents();
        }
Beispiel #4
0
        internal PluginData(IConfigurationSolver solver, IPluginInfo p, ServiceData service, ConfigurationStatus pluginStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown)
        {
            _solver              = solver;
            PluginInfo           = p;
            Service              = service;
            ConfigOriginalStatus = pluginStatus;
            switch (pluginStatus)
            {
            case ConfigurationStatus.Disabled: _configSolvedStatus = SolvedConfigurationStatus.Disabled; break;

            case ConfigurationStatus.Running: _configSolvedStatus = SolvedConfigurationStatus.Running; break;

            default: _configSolvedStatus = SolvedConfigurationStatus.Runnable; break;
            }
            _configSolvedStatusReason = PluginRunningRequirementReason.Config;

            RawConfigSolvedImpact = ConfigOriginalImpact = impact;
            if (RawConfigSolvedImpact == StartDependencyImpact.Unknown && Service != null)
            {
                RawConfigSolvedImpact = Service.ConfigSolvedImpact;
            }
            _configSolvedImpact = RawConfigSolvedImpact;
            if (_configSolvedImpact == StartDependencyImpact.Unknown || (_configSolvedImpact & StartDependencyImpact.IsTryOnly) != 0)
            {
                _configSolvedImpact = StartDependencyImpact.Minimal;
            }

            if (ConfigOriginalStatus == ConfigurationStatus.Disabled)
            {
                _configDisabledReason = PluginDisabledReason.Config;
            }
            else if (p.HasError)
            {
                _configDisabledReason = PluginDisabledReason.PluginInfoHasError;
            }
            else if (Service != null)
            {
                if (Service.Disabled)
                {
                    _configDisabledReason = PluginDisabledReason.ServiceIsDisabled;
                }
                else if (Service.Family.RunningPlugin != null)
                {
                    _configDisabledReason = PluginDisabledReason.AnotherRunningPluginExistsInFamilyByConfig;
                }
            }
            // Immediately check for Runnable references to Disabled Services: this disables us.
            if (!Disabled)
            {
                foreach (var sRef in PluginInfo.ServiceReferences)
                {
                    if (sRef.Requirement >= DependencyRequirement.Runnable)
                    {
                        // If the required service is already disabled, we immediately disable this plugin.
                        if (sRef.Reference.HasError && !Disabled)
                        {
                            _configDisabledReason = PluginDisabledReason.RunnableReferenceServiceIsOnError;
                            break;
                        }
                        ServiceData sr = _solver.FindExistingService(sRef.Reference.ServiceFullName);
                        if (sr.Disabled && !Disabled)
                        {
                            _configDisabledReason = PluginDisabledReason.RunnableReferenceIsDisabled;
                            break;
                        }
                    }
                }
            }
            if (Service != null)
            {
                Service.AddPlugin(this);
            }
            if (!Disabled)
            {
                // If the plugin is not yet disabled, we register it:
                // whenever the referenced service is disabled (or stopped during dynamic resolution), this
                // will disable (or stop) the plugin according to its ConfigSolvedImpact.
                foreach (var sRef in PluginInfo.ServiceReferences)
                {
                    _solver.FindExistingService(sRef.Reference.ServiceFullName).RegisterPluginReference(this, sRef.Requirement);
                }
                if (Service != null && ConfigOriginalStatus == ConfigurationStatus.Running)
                {
                    Service.Family.SetRunningPlugin(this);
                }
            }
        }
        internal PluginData( IConfigurationSolver solver, IPluginInfo p, ServiceData service, ConfigurationStatus pluginStatus, StartDependencyImpact impact = StartDependencyImpact.Unknown )
        {
            _solver = solver;
            PluginInfo = p;
            Service = service;
            ConfigOriginalStatus = pluginStatus;
            switch( pluginStatus )
            {
                case ConfigurationStatus.Disabled: _configSolvedStatus = SolvedConfigurationStatus.Disabled; break;
                case ConfigurationStatus.Running: _configSolvedStatus = SolvedConfigurationStatus.Running; break;
                default: _configSolvedStatus = SolvedConfigurationStatus.Runnable; break;
            }
            _configSolvedStatusReason = PluginRunningRequirementReason.Config;

            RawConfigSolvedImpact = ConfigOriginalImpact = impact;
            if( RawConfigSolvedImpact == StartDependencyImpact.Unknown && Service != null )
            {
                RawConfigSolvedImpact = Service.ConfigSolvedImpact;
            }
            _configSolvedImpact = RawConfigSolvedImpact;
            if( _configSolvedImpact == StartDependencyImpact.Unknown || (_configSolvedImpact & StartDependencyImpact.IsTryOnly) != 0 )
            {
                _configSolvedImpact = StartDependencyImpact.Minimal;
            }

            if( ConfigOriginalStatus == ConfigurationStatus.Disabled )
            {
                _configDisabledReason = PluginDisabledReason.Config;
            }
            else if( p.HasError )
            {
                _configDisabledReason = PluginDisabledReason.PluginInfoHasError;
            }
            else if( Service != null )
            {
                if( Service.Disabled )
                {
                    _configDisabledReason = PluginDisabledReason.ServiceIsDisabled;
                }
                else if( Service.Family.RunningPlugin != null )
                {
                    _configDisabledReason = PluginDisabledReason.AnotherRunningPluginExistsInFamilyByConfig;
                }
            }
            // Immediately check for Runnable references to Disabled Services: this disables us.
            if( !Disabled )
            {
                foreach( var sRef in PluginInfo.ServiceReferences )
                {
                    if( sRef.Requirement >= DependencyRequirement.Runnable )
                    {
                        // If the required service is already disabled, we immediately disable this plugin.
                        if( sRef.Reference.HasError && !Disabled )
                        {
                            _configDisabledReason = PluginDisabledReason.RunnableReferenceServiceIsOnError;
                            break;
                        }
                        ServiceData sr = _solver.FindExistingService( sRef.Reference.ServiceFullName );
                        if( sr.Disabled && !Disabled )
                        {
                            _configDisabledReason = PluginDisabledReason.RunnableReferenceIsDisabled;
                            break;
                        }
                    }
                }
            }
            if( Service != null ) Service.AddPlugin( this );
            if( !Disabled  )
            {
                // If the plugin is not yet disabled, we register it:
                // whenever the referenced service is disabled (or stopped during dynamic resolution), this
                // will disable (or stop) the plugin according to its ConfigSolvedImpact.
                foreach( var sRef in PluginInfo.ServiceReferences )
                {
                    _solver.FindExistingService( sRef.Reference.ServiceFullName ).RegisterPluginReference( this, sRef.Requirement );
                }
                if( Service != null && ConfigOriginalStatus == ConfigurationStatus.Running )
                {
                    Service.Family.SetRunningPlugin( this );
                }
            }
        }