Example #1
0
        public void Start()
        {
            _pluginDescriptors = PluginManager.Sort(_pluginDescriptors, true);

            // start plugins
            PluginManager.StartPlugins(_pluginDescriptors);
        }
Example #2
0
        public void Stop()
        {
            // sort plugins to have the most dependent plugins first
            _pluginDescriptors = PluginManager.Sort(_pluginDescriptors, false);

            // stop plugins
            PluginManager.StopPlugins(_pluginDescriptors);
        }
Example #3
0
        /// <summary>
        /// Validates the dependencies for each of the PluginDescriptors
        /// </summary>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void ValidatePluginDependencies(PluginDescriptorCollection descriptors)
        {
            /*
             * Validation Phases
             * Phase 1: Direct		(First level dependencies)
             * Phase 2: Indirect	(Second level dependencies. i.e., dependencies of dependencies. Requires that Phase 1 already executed)
             * Phase 3: Extended	(Provider Validation)
             * */

            // Phase 1: Checks descriptors for missing dependencies and circular references. (direct)
            foreach (PluginDescriptor descriptor in descriptors)
            {
                try
                {
                    // check for missing dependencies
                    //					MarkDescriptorIfMissingDependency(descriptor, descriptors);
                    if (!descriptor.IsMissingDependency)
                    {
                        // check for circular references between plugins (direct, does not check dependency chains)
                        MarkDescriptorIfCircularlyDependent(descriptor, descriptors);
                    }
                }
                catch (Exception ex)
                {
                    CairoLogger.Instance.Debug(ex.Message, ex);
                }
            }

            // Phase 2: Checks depencencies for missing dependencies and circular references. (indirect)
            foreach (PluginDescriptor descriptor in descriptors)
            {
                try
                {
                    //
                    if (!descriptor.IsMissingDependency && !descriptor.IsCircularlyDependent)
                    {
                        MarkDescriptorIfDependenciesAreMissingDependencyOrAreCircularlyDependent(descriptor, descriptors);
                    }
                }
                catch (Exception ex)
                {
                    CairoLogger.Instance.Debug(ex.Message, ex);
                }
            }

            // Phase 3: Allow for Provider based validation?

            /*
             * Here we have an extension point.
             * If we created another provider who's sole purpose was to validate a PluginDescriptor,
             * we could move this logic away from the core, and allow for validation to be extended.
             * Possible reasons for doing this would be to prevent Plugins from being loaded based
             * on some other criteria. We could provide descriptions of why a particular descriptor failed validation.
             * */
        }
Example #4
0
 /// <summary>
 /// Determines if the dependencies for a PluginDescriptor are created.
 /// </summary>
 /// <param name="descriptor">The descriptor to check dependencies for.</param>
 /// <param name="descriptors">The collection of PluginDescriptor(s) to check against.</param>
 /// <returns></returns>
 private static bool AreDependenciesCreated(PluginDescriptor descriptor, PluginDescriptorCollection descriptors)
 {
     foreach (Type type in descriptor.PluginDependencies)
     {
         if (descriptors[type].PluginInstance == null)
         {
             return(false);
         }
     }
     return(true);
 }
Example #5
0
        /// <summary>
        /// Sorts the collection of PluginDescriptors according to their dependency chain.
        /// </summary>
        /// <param name="descriptorCollection">The collection of descriptors to sort.</param>
        /// <param name="leastDependentFirst">A flag that determines how the descriptors are sorted.</param>
        /// <returns></returns>
        public static PluginDescriptorCollection Sort(PluginDescriptorCollection descriptorCollection, bool leastDependentFirst)
        {
            CairoLogger.Instance.Debug(string.Format("Sorting PluginDescriptor Collection. LeastDependentFirst: '{0}'.", leastDependentFirst.ToString()));



            PluginDescriptor[] descriptors = descriptorCollection.ToArray();
            PluginDescriptor.Sort(descriptors, leastDependentFirst);

            descriptorCollection.Clear();
            descriptorCollection.Add(descriptors);

            return(descriptorCollection);
        }
Example #6
0
        /// <summary>
        /// Creates instances of the Plugin type defined by each PluginDescriptor.
        /// </summary>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void CreatePluginInstances(PluginDescriptorCollection descriptors)
        {
            CairoLogger.Instance.Debug(string.Format("Creating Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString()));

            foreach (PluginDescriptor descriptor in descriptors)
            {
                if (descriptor.IsStartable)
                {
                    if (AreDependenciesCreated(descriptor, descriptors))
                    {
                        CreatePluginInstance(descriptor);
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// Stops the plugins defined in the collection that have been created.
        /// </summary>
        /// <param name="descriptors">The collection of PluginDescriptors that describe the Plugins to be loaded.</param>
        public static void StopPlugins(PluginDescriptorCollection descriptors)
        {
            CairoLogger.Instance.Debug(string.Format("Stopping Plugins. # of Plugins: '{0}'.", descriptors.Count.ToString()));

            // fire the BeforePluginsStopped event of the PluginContext
            PluginContext.Current.OnBeforePluginsStopped(new PluginContextEventArgs(PluginContext.Current));

            // stop all of the plugins
            foreach (PluginDescriptor descriptor in descriptors)
            {
                if (descriptor.PluginInstance != null)
                {
                    StopPlugin(descriptor);
                }
                else
                {
                    CairoLogger.Instance.Debug(string.Format("Skipped Plugin: '{0}' was not created.", descriptor.PluginName));
                }
            }
        }
Example #8
0
        /// <summary>
        /// Begins a new application plugin context. Should only be called once.
        /// </summary>
        public void Initialize(PluginProviderCollection pluginProviders)
        {
            // load the core sub-system providers
            _pluginProviders = pluginProviders;

            // use the plugin manager to load the plugin types that the plugin providers want loaded
            using (TypeCollection pluginTypes = PluginManager.LoadPluginTypes(_pluginProviders))
            {
                // use the plugin manager to create descriptors for all of the plugins
                _pluginDescriptors = PluginManager.CreatePluginDescriptors(pluginTypes);

                // validate the plugin dependencies
                PluginManager.ValidatePluginDependencies(_pluginDescriptors);

                // sort plugins to have the least dependent plugins first
                _pluginDescriptors = PluginManager.Sort(_pluginDescriptors, true);

                // create the plugins
                PluginManager.CreatePluginInstances(_pluginDescriptors);
            }
        }
Example #9
0
        /// <summary>
        /// Creates PluginDescriptors from each Plugin Type specified.
        /// </summary>
        /// <param name="types">The collection of Plugin Types to create descriptors for.</param>
        /// <returns></returns>
        public static PluginDescriptorCollection CreatePluginDescriptors(TypeCollection types)
        {
            var descriptors = new PluginDescriptorCollection();

            foreach (Type type in types)
            {
                try
                {
                    CairoLogger.Instance.Debug(string.Format("Creating PluginDescriptor, Type: '{0}'.", type.FullName));

                    var descriptor = new PluginDescriptor(type);

                    descriptors.Add(descriptor);
                }
                catch (Exception ex)
                {
                    CairoLogger.Instance.Debug(ex.Message, ex);
                }
            }
            return(descriptors);
        }
Example #10
0
        /// <summary>
        /// Cleanup any managed resources
        /// </summary>
        protected override void DisposeOfManagedResources()
        {
            base.DisposeOfManagedResources();

            if (_pluginProviders != null)
            {
                _pluginProviders.Dispose();
                _pluginProviders = null;
            }

            if (_pluginDescriptors != null)
            {
                _pluginDescriptors.Dispose();
                _pluginDescriptors = null;
            }

            if (_gcTimer != null)
            {
                _gcTimer.Dispose();
                _gcTimer = null;
            }
        }
Example #11
0
        /// <summary>
        /// Marks a descriptor if it has dependencies that themselves are missing dependencies or are circularly dependent
        /// </summary>
        /// <param name="descriptor">The descriptor to check</param>
        /// <param name="descriptors">The collection of PluginDescriptors to check against</param>
        private static void MarkDescriptorIfDependenciesAreMissingDependencyOrAreCircularlyDependent(PluginDescriptor descriptor, PluginDescriptorCollection descriptors)
        {
            // check each dependency in that descriptor depends on
            foreach (Type type in descriptor.PluginDependencies)
            {
                // against all the other descriptors
                foreach (PluginDescriptor otherDescriptor in descriptors)
                {
                    // when we find a descriptor that describes the Type the first descriptor needs
                    if (otherDescriptor.PluginType == type)
                    {
                        // the other dependency better not be missing a dependency
                        if (otherDescriptor.IsMissingDependency)
                        {
                            // if it does, the whole chain is jacked
                            descriptor.IsDependentOnTypeThatIsMissingDependency = true;
                            return;
                        }

                        // the other dependency better not be circularly dependent
                        if (otherDescriptor.IsCircularlyDependent)
                        {
                            // if it does, the whole chain is jacked
                            descriptor.IsDependentOnTypeThatIsCircularlyDependent = true;
                            return;
                        }
                    }
                }
            }
        }
Example #12
0
 /// <summary>
 /// Marks a descriptor if is is circularly dependent with any other descriptor
 /// </summary>
 /// <param name="descriptor">The descriptor to check</param>
 /// <param name="descriptors">The collection of PluginDescriptors to check against</param>
 private static void MarkDescriptorIfCircularlyDependent(PluginDescriptor descriptor, PluginDescriptorCollection descriptors)
 {
     // check each dependency in that descriptor depends on
     foreach (Type type in descriptor.PluginDependencies)
     {
         // against all the other descriptors
         foreach (PluginDescriptor otherDescriptor in descriptors)
         {
             // when we find a descriptor that describes the Type the first descriptor needs
             if (otherDescriptor.PluginType == type)
             {
                 // it better not depend on the first
                 if (otherDescriptor.DependsOn(descriptor))
                 {
                     // if it does, it's a circular dependency which we cannot have
                     descriptor.IsCircularlyDependent = true;
                     return;
                 }
             }
         }
     }
 }