Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/27/09 14:45:01 (14 years ago)
Author:
gkronber
Message:

Implemented cycle detection of plugin dependencies. #799

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2527 r2536  
    7777    /// 1. All assemblies in the plugins directory are loaded into the reflection only context.
    7878    /// 2. The validator checks if all necessary files for each plugin are available.
    79     /// 3. The validator builds the tree of plugin descriptions (dependencies)
    80     /// 4. The validator checks if all dependencies for each plugin are ok.
    81     /// 5. All plugins for which there are no dependencies missing are loaded into the execution context.
    82     /// 6. Each loaded plugin (all assemblies) is searched for a types that implement IPlugin
     79    /// 3. The validator checks if all declared plugin assemblies can be loaded.
     80    /// 4. The validator builds the tree of plugin descriptions (dependencies)
     81    /// 5. The validator checks if there are any cycles in the plugin dependency graph and disables plugin with circular dependencies
     82    /// 6. The validator checks for each plugin if any dependency is disabled.
     83    /// 7. All plugins that are not disabled are loaded into the execution context.
     84    /// 8. Each loaded plugin (all assemblies) is searched for a types that implement IPlugin
    8385    ///    then one instance of each IPlugin type is activated and the OnLoad hook is called.
    84     /// 7. All types implementing IApplication are discovered
     86    /// 9. All types implementing IApplication are discovered
    8587    /// </summary>
    8688    internal void DiscoverAndCheckPlugins() {
     
    9193      CheckPluginFiles(pluginDescriptions);
    9294
     95      // check if all plugin assemblies can be loaded
    9396      CheckPluginAssemblies(pluginDescriptions);
    9497
    9598      // a full list of plugin descriptions is available now we can build the dependency tree
    9699      BuildDependencyTree(pluginDescriptions);
     100
     101      // check for dependency cycles
     102      CheckPluginDependencyCycles(pluginDescriptions);
    97103
    98104      // recursively check if all necessary plugins are available and not disabled
     
    100106      CheckPluginDependencies(pluginDescriptions);
    101107
    102       // mark all plugins as enabled that were not disabled in CheckPluginFiles or CheckPluginDependencies
     108      // mark all plugins as enabled that were not disabled in CheckPluginFiles, CheckPluginAssemblies,
     109      // CheckCircularDependencies, or CheckPluginDependencies
    103110      foreach (var desc in pluginDescriptions)
    104111        if (desc.PluginState != PluginState.Disabled)
     
    300307    }
    301308
     309    private void CheckPluginDependencyCycles(IEnumerable<PluginDescription> pluginDescriptions) {
     310      foreach (var plugin in pluginDescriptions) {
     311        // if the plugin is not disabled anyway check if there are cycles
     312        if (plugin.PluginState != PluginState.Disabled && HasCycleInDependencies(plugin, plugin.Dependencies)) {
     313          plugin.Disable();
     314        }
     315      }
     316    }
     317
     318    private bool HasCycleInDependencies(PluginDescription plugin, IEnumerable<PluginDescription> pluginDependencies) {
     319      foreach (var dep in pluginDependencies) {
     320        // if one of the dependencies is the original plugin we found a cycle and can return
     321        // if the dependency is already disabled we can ignore the cycle detection because we will disable the plugin anyway
     322        // if following one of the dependencies recursively leads to a cycle then we also return
     323        if (dep == plugin || dep.PluginState == PluginState.Disabled || HasCycleInDependencies(plugin, dep.Dependencies)) return true;
     324      }
     325      // no cycle found and none of the direct and indirect dependencies is disabled
     326      return false;
     327    }
     328
    302329    private void CheckPluginDependencies(IEnumerable<PluginDescription> pluginDescriptions) {
    303330      foreach (PluginDescription pluginDescription in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
Note: See TracChangeset for help on using the changeset viewer.