Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.PluginInfrastructure/PluginManager.cs @ 19

Last change on this file since 19 was 2, checked in by swagner, 17 years ago

Added HeuristicLab 3.0 sources from former SVN repository at revision 52

File size: 6.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24
25namespace HeuristicLab.PluginInfrastructure {
26
27  // must extend MarshalByRefObject because of event passing between Loader and PluginManager (each in it's own AppDomain)
28  public class PluginManager : MarshalByRefObject {
29
30    // singleton: only one manager allowed in each AppDomain
31    private static PluginManager manager = new PluginManager();
32    public static PluginManager Manager {
33      get { return manager; }
34    }
35
36    // singleton: only one control manager allowed in each applicatoin (i.e. AppDomain)
37    private static IControlManager controlManager;
38    public static IControlManager ControlManager {
39      get { return controlManager; }
40      set { controlManager = value; }
41    }
42
43    public event PluginManagerActionEventHandler Action;
44
45    // holds a proxy for the loader in the special AppDomain for PluginManagament
46    private Loader remoteLoader;
47    private AppDomain pluginDomain;
48    private string pluginDir;
49
50    // singleton pattern
51    private PluginManager() {
52      this.pluginDir = HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir;
53    }
54
55    public List<PluginInfo> InstalledPlugins {
56      get { return remoteLoader.InstalledPlugins; }
57    }
58
59    public ApplicationInfo[] InstalledApplications {
60      get { return remoteLoader.InstalledApplications; }
61    }
62
63    private PluginInfo[] loadedPlugins;
64    public PluginInfo[] LoadedPlugins {
65      get { return loadedPlugins; }
66      internal set { loadedPlugins = value; }
67    }
68
69    /// <summary>
70    /// Creates a dedicated AppDomain for loading all plugins and checking dependencies.
71    /// </summary>
72    public void Initialize() {
73      NotifyListeners(PluginManagerAction.Initializing, "-");
74
75      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
76      setup.PrivateBinPath = pluginDir;
77      pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup);
78
79      remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure", "HeuristicLab.PluginInfrastructure.Loader");
80
81      remoteLoader.PluginAction += delegate(object sender, PluginManagerActionEventArgs args) { if(Action != null) Action(this, args); };
82      remoteLoader.Init();
83
84      NotifyListeners(PluginManagerAction.Initialized, "-");
85    }
86
87    /// <summary>
88    /// Creates a separate AppDomain.
89    /// Loads all active plugin assemblies and starts the application in the new AppDomain via a PluginRunner instance activated in the new AppDomain
90    /// </summary>
91    /// <param name="appInfo">application to run</param>
92    public void Run(ApplicationInfo appInfo) {
93      // create a separate AppDomain for the application
94      // activate a PluginRunner instance in the application
95      // and remotely tell it to start the application
96
97      NotifyListeners(PluginManagerAction.Starting, appInfo.Name);
98      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
99      setup.PrivateBinPath = pluginDir;
100      AppDomain applicationDomain = AppDomain.CreateDomain(appInfo.Name + " AppDomain", null, setup);
101     
102      Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfrastructure", "HeuristicLab.PluginInfrastructure.Runner");
103      NotifyListeners(PluginManagerAction.Initializing, "All plugins");
104      remoteRunner.LoadPlugins(remoteLoader.ActivePlugins);
105      NotifyListeners(PluginManagerAction.Initialized, "All plugins");
106      remoteRunner.Run(appInfo);
107
108      AppDomain.Unload(applicationDomain);
109    }
110
111    /// <summary>
112    /// Calculates a set of plugins that directly or transitively depend on the plugin given in the argument.
113    /// </summary>
114    /// <param name="pluginInfo"></param>
115    /// <returns>a list of plugins that are directly of transitively dependent.</returns>
116    public List<PluginInfo> GetDependentPlugins(PluginInfo pluginInfo) {
117      List<PluginInfo> mergedList = new List<PluginInfo>();
118      InstalledPlugins.ForEach(delegate(PluginInfo plugin) {
119        if(plugin.Dependencies.Contains(pluginInfo)) {
120          if(!mergedList.Contains(plugin)) {
121            mergedList.Add(plugin);
122          }
123          // for each of the dependent plugins add the list of transitively dependent plugins
124          // make sure that only one entry for each plugin is added to the merged list
125          GetDependentPlugins(plugin).ForEach(delegate(PluginInfo dependentPlugin) {
126            if(!mergedList.Contains(dependentPlugin)) {
127              mergedList.Add(dependentPlugin);             
128            }
129          });
130        }
131      });
132     
133      return mergedList;
134    }
135
136    public void UnloadAllPlugins() {
137      AppDomain.Unload(pluginDomain);
138    }
139
140    public void LoadAllPlugins() {
141      Initialize();
142    }
143
144    public void OnDelete(PluginInfo pluginInfo) {
145      remoteLoader.OnDelete(pluginInfo);
146    }
147
148    public void OnInstall(PluginInfo pluginInfo) {
149      remoteLoader.OnInstall(pluginInfo);
150    }
151
152    public void OnPreUpdate(PluginInfo pluginInfo) {
153      remoteLoader.OnPreUpdate(pluginInfo);
154    }
155
156    public void OnPostUpdate(PluginInfo pluginInfo) {
157      remoteLoader.OnPostUpdate(pluginInfo);
158    }
159
160    private void NotifyListeners(PluginManagerAction action, string text) {
161      if(Action != null) {
162        Action(this, new PluginManagerActionEventArgs(text, action));
163      }
164    }
165  }
166}
Note: See TracBrowser for help on using the repository browser.