Changeset 2497 for branches/PluginInfrastructure Refactoring
- Timestamp:
- 11/16/09 18:30:04 (15 years ago)
- Location:
- branches/PluginInfrastructure Refactoring
- Files:
-
- 9 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.GUI/HeuristicLab.PluginInfrastructure.GUI.csproj
r1474 r2497 110 110 </Compile> 111 111 <Compile Include="PluginAction.cs" /> 112 <Compile Include="PluginDescription.cs" />113 112 <Compile Include="PluginNameTransform.cs" /> 114 113 <Compile Include="PluginSource.cs" /> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationDescription.cs
r2488 r2497 84 84 set { declaringTypeName = value; } 85 85 } 86 87 public override string ToString() { 88 return Name; 89 } 86 90 } 87 91 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/DefaultApplicationManager.cs
r2495 r2497 44 44 public IEnumerable<IPluginDescription> Plugins { 45 45 get { return plugins; } 46 internal set { plugins = new List<IPluginDescription>(value); } 46 47 } 47 48 … … 82 83 foreach (var plugin in GetInstances<IPlugin>(asm)) { 83 84 plugin.OnLoad(); 84 FirePluginLoaded(plugin.Name);85 85 } 86 86 } 87 FirePluginLoaded(desc); 87 88 desc.Load(); 88 89 } 89 90 90 } 91 91 … … 203 203 } 204 204 205 private void FirePluginLoaded( string name) {206 if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", name));205 private void FirePluginLoaded(IPluginDescription plugin) { 206 if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", plugin)); 207 207 } 208 208 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj
r2489 r2497 49 49 <ItemGroup> 50 50 <Compile Include="ApplicationDescription.cs" /> 51 <Compile Include="ApplicationManager.cs"> 52 <SubType>Code</SubType> 53 </Compile> 51 <Compile Include="DefaultApplicationManager.cs" /> 54 52 <Compile Include="Loader.cs" /> 55 53 <Compile Include="PluginDescription.cs" /> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs
r2495 r2497 38 38 internal IEnumerable<ApplicationDescription> Applications { 39 39 get { 40 if (applications == null) DiscoverAndCheckPlugins(); 40 41 return applications; 41 42 } … … 45 46 internal IEnumerable<PluginDescription> Plugins { 46 47 get { 48 if (plugins == null) DiscoverAndCheckPlugins(); 47 49 return plugins; 48 50 } … … 52 54 53 55 public Loader() { 54 this.applications = new List<ApplicationDescription>();55 this.plugins = new List<PluginDescription>();56 56 this.pluginDependencies = new Dictionary<PluginDescription, List<string>>(); 57 57 58 // ReflectionOnlyAssemblyResolveEvent must be handled because we load assemblies from the plugin path 59 // (which is not listed in the default assembly lookup locations) 58 60 AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveEventHandler; 59 61 } 60 62 61 63 private Assembly ReflectionOnlyAssemblyResolveEventHandler(object sender, ResolveEventArgs args) { 62 //try {63 64 return Assembly.ReflectionOnlyLoad(args.Name); 64 //}65 //catch (FileLoadException ex) {66 // return null;67 //}68 65 } 69 66 … … 80 77 /// 7. All types implementing IApplication are discovered 81 78 /// </summary> 82 internal void Init() {79 private void DiscoverAndCheckPlugins() { 83 80 pluginDependencies.Clear(); 84 81 … … 163 160 } 164 161 } 162 // ignore exceptions. Just don't yield a plugin description when an exception is thrown 165 163 catch (FileNotFoundException) { 166 164 } … … 310 308 311 309 /// <summary> 312 /// Initializes the life time service with an infin te lease time.310 /// Initializes the life time service with an infinite lease time. 313 311 /// </summary> 314 312 /// <returns><c>null</c>.</returns> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs
r2488 r2497 135 135 } 136 136 137 138 //private string message;139 ///// <summary>140 ///// Gets or sets the message.141 ///// </summary>142 //public string Message {143 // get { return message; }144 // set { message = value; }145 //}146 147 137 /// <summary> 148 138 /// Gets the string representation of the plugin. … … 153 143 } 154 144 155 // //equals and hashcode have to be implemented because we want to compare PluginDescriptions from156 // //different AppDomains and serialization destroys reference equality157 /// //<summary>158 /// //Checks whether the given object is equal to the current plugin.159 /// //</summary>160 /// //<param name="obj">The object to compare.</param>161 /// //<returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns>162 //public override bool Equals(object obj) {163 //if (!(obj is PluginDescription))164 //return false;165 //PluginDescription other = (PluginDescription)obj;145 // equals and hashcode have to be implemented because we want to compare PluginDescriptions from 146 // different AppDomains and serialization destroys reference equality 147 /// <summary> 148 /// Checks whether the given object is equal to the current plugin. 149 /// </summary> 150 /// <param name="obj">The object to compare.</param> 151 /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns> 152 public override bool Equals(object obj) { 153 if (!(obj is PluginDescription)) 154 return false; 155 PluginDescription other = (PluginDescription)obj; 166 156 167 //return other.Name == this.Name && other.Version == this.Version;168 //}169 /// //<summary>170 /// //Gets the hash code of the current plugin.171 /// //</summary>172 /// //<returns>The hash code of the plugin.</returns>173 //public override int GetHashCode() {174 //if (version != null) {175 //return name.GetHashCode() + version.GetHashCode();176 //} else return name.GetHashCode();177 //}157 return other.Name == this.Name && other.Version == this.Version; 158 } 159 /// <summary> 160 /// Gets the hash code of the current plugin. 161 /// </summary> 162 /// <returns>The hash code of the plugin.</returns> 163 public override int GetHashCode() { 164 if (version != null) { 165 return name.GetHashCode() + version.GetHashCode(); 166 } else return name.GetHashCode(); 167 } 178 168 } 179 169 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs
r2489 r2497 29 29 public class PluginInfrastructureEventArgs : EventArgs { 30 30 public string Action { get; private set; } 31 public string EntityName{ get; private set; }32 public PluginInfrastructureEventArgs(string action, string entityName) {33 Action = action;34 EntityName = entityName;31 public object Entity { get; private set; } 32 public PluginInfrastructureEventArgs(string action, object entity) { 33 this.Action = action; 34 this.Entity = entity; 35 35 } 36 36 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs
r2489 r2497 43 43 private string pluginDir; 44 44 45 // singleton pattern46 45 public PluginManager(string pluginDir) { 47 46 this.pluginDir = pluginDir; 48 47 } 49 48 50 ///// <summary>51 ///// Gets all installed plugins.52 ///// </summary>53 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>54 //public ICollection<PluginInfo> InstalledPlugins {55 // get { return remoteLoader.InstalledPlugins; }56 //}57 58 ///// <summary>59 ///// Gets all disabled plugins.60 ///// </summary>61 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>62 //public ICollection<PluginInfo> DisabledPlugins {63 // get { return remoteLoader.DisabledPlugins; }64 //}65 66 ///// <summary>67 ///// Gets all active plugins.68 ///// </summary>69 ///// <remarks>This information is provided by a <see cref="Loader"/>.</remarks>70 //public ICollection<PluginInfo> ActivePlugins {71 // get { return remoteLoader.ActivePlugins; }72 //}73 74 //private ICollection<PluginInfo> loadedPlugins;75 ///// <summary>76 ///// Gets or (internally) sets the loaded plugins.77 ///// </summary>78 //public ICollection<PluginInfo> LoadedPlugins {79 // get { return loadedPlugins; }80 // internal set { loadedPlugins = value; }81 //}82 83 49 private List<PluginDescription> plugins; 84 //public IEnumerable<PluginDescription> Plugins {85 // get { return plugins; }86 //}87 50 88 51 private List<ApplicationDescription> applications; … … 97 60 /// Determines installed plugins and checks if all plugins are loadable. 98 61 /// </summary> 99 public void Initialize() {100 NotifyListeners("Initializing", "PluginInfrastructure");62 public void DiscoverAndCheckPlugins() { 63 FireAction("Initializing", "PluginInfrastructure"); 101 64 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 102 65 setup.PrivateBinPath = pluginDir; 103 AppDomain pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup); 104 Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader"); 105 remoteLoader.PluginDir = pluginDir; 106 remoteLoader.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); }; // forward all events from the remoteLoader to listeners 107 remoteLoader.Init(); 108 NotifyListeners("Initialized", "PluginInfrastructure"); 109 110 plugins = new List<PluginDescription>(remoteLoader.Plugins); 111 applications = new List<ApplicationDescription>(remoteLoader.Applications); 112 113 // discard the AppDomain that was used for plugin discovery 114 UnloadAppDomain(pluginDomain); 66 AppDomain pluginDomain = null; 67 try { 68 pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup); 69 Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader"); 70 remoteLoader.PluginDir = pluginDir; 71 // forward all events from the remoteLoader to listeners 72 remoteLoader.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { FireAction(args.Action, args.Entity); }; 73 this.plugins = new List<PluginDescription>(remoteLoader.Plugins); 74 this.applications = new List<ApplicationDescription>(remoteLoader.Applications); 75 FireAction("Initialized", "PluginInfrastructure"); 76 } 77 finally { 78 // discard the AppDomain that was used for plugin discovery 79 UnloadAppDomain(pluginDomain); 80 } 115 81 } 116 82 117 private void UnloadAppDomain(AppDomain appDomain) {118 AppDomain.Unload(appDomain);119 120 // set all loaded plugins back to enabled121 foreach (var pluginDescription in plugins)122 pluginDescription.Unload();123 }124 125 126 ///// <summary>127 ///// Creates a new AppDomain with all plugins preloaded.128 ///// </summary>129 ///// <param name="friendlyName">Name of the new AppDomain</param>130 ///// <returns>the new AppDomain with all plugins preloaded.</returns>131 //public AppDomain CreateAndInitAppDomain(string friendlyName) {132 133 // return applicationDomain;134 //}135 83 136 84 /// <summary> … … 144 92 // and remotely tell it to start the application 145 93 146 NotifyListeners("Starting application", appInfo.Name);94 FireAction("Starting application", appInfo.Name); 147 95 AppDomain applicationDomain = null; 148 96 try { … … 152 100 DefaultApplicationManager applicationManager = 153 101 (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager"); 154 applicationManager.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); };102 applicationManager.PluginLoaded += applicationManager_PluginLoaded; 155 103 applicationManager.PrepareApplicationDomain( 156 104 new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()), 157 105 new List<IPluginDescription>(plugins.Cast<IPluginDescription>())); 158 NotifyListeners("Started application", appInfo.Name);106 FireAction("Started application", appInfo.Name); 159 107 applicationManager.Run(appInfo); 160 108 } 161 109 finally { 162 110 // make sure domain is unloaded in all cases 163 if (applicationDomain != null) AppDomain.Unload(applicationDomain);111 UnloadAppDomain(applicationDomain); 164 112 } 165 113 } 166 114 167 ///// <summary>168 ///// Creates a new AppDomain with all plugins preloaded and Sandboxing capability.169 ///// </summary>170 ///// <param name="assembly">Assembly reference</param>171 ///// <returns>the strongname of the assembly</returns>172 //private StrongName CreateStrongName(Assembly assembly) {173 // if (assembly == null)174 // throw new ArgumentNullException("assembly");115 void applicationManager_PluginLoaded(object sender, PluginInfrastructureEventArgs e) { 116 // load the matching plugin description ( 117 PluginDescription desc = (PluginDescription)e.Entity; 118 foreach (var myDesc in plugins) { 119 if (myDesc.Equals(desc)) myDesc.Load(); 120 } 121 FireAction(e.Action, e.Entity); 122 } 175 123 176 // AssemblyName assemblyName = assembly.GetName();177 // Debug.Assert(assemblyName != null, "Could not get assembly name");124 private void UnloadAppDomain(AppDomain appDomain) { 125 AppDomain.Unload(appDomain); 178 126 179 // // get the public key blob 180 // byte[] publicKey = assemblyName.GetPublicKey(); 181 // if (publicKey == null || publicKey.Length == 0) 182 // throw new InvalidOperationException("Assembly is not strongly named"); 127 // TODO: Update plugin descriptions in all active AppDomains 183 128 184 // StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey); 129 // unload all plugins 130 foreach (var pluginDescription in plugins) 131 pluginDescription.Unload(); 132 } 185 133 186 // // and create the StrongName 187 // return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version); 188 //} 189 190 //public AppDomain CreateAndInitAppDomainWithSandbox(string friendlyName, bool sandboxed, Type jobType, ICollection<byte[]> assemblyFiles) { 191 // PermissionSet pset; 192 193 194 195 // //DiscoveryService dService = new DiscoveryService(); 196 // //get the declaring plugin of the job 197 // //PluginInfo jobPlugin = dService.GetDeclaringPlugin(jobType); 198 199 // //get all the plugins that have dependencies with the jobplugin 200 // //List<PluginInfo> depPlugins = GetDependentPluginsRec(jobPlugin); 201 // //insert all jobs into one list 202 // //depPlugins.Add(jobPlugin); 203 204 // if (sandboxed) { 205 // pset = new PermissionSet(PermissionState.None); 206 // pset.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); 207 // pset.AddPermission(new ReflectionPermission(PermissionState.Unrestricted)); 208 // FileIOPermission fPerm = new FileIOPermission(PermissionState.None); 209 210 // /*foreach (PluginInfo plugin in depPlugins) { 211 // foreach(String assemblies in plugin.Assemblies) 212 // fPerm.AddPathList(FileIOPermissionAccess.AllAccess, assemblies); 213 // } 214 215 // pset.AddPermission(fPerm);*/ 216 217 // } else { 218 // pset = new PermissionSet(PermissionState.Unrestricted); 219 // } 220 // AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 221 // setup.PrivateBinPath = pluginDir; 222 // setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase; 223 // AppDomain applicationDomain = AppDomain.CreateDomain(friendlyName, AppDomain.CurrentDomain.Evidence, setup, pset, CreateStrongName(Assembly.GetExecutingAssembly())); 224 // Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName); 225 // NotifyListeners("Initializing", "All plugins"); 226 227 // if (assemblyFiles != null && assemblyFiles.Count > 0) 228 // remoteRunner.LoadAssemblies(assemblyFiles); 229 230 // //if (depPlugins != null && depPlugins.Count > 0) { 231 // //remoteRunner.LoadPlugins(ActivePlugins); 232 // //} 233 // NotifyListeners("Initialized", "All plugins"); 234 // return applicationDomain; 235 //} 236 237 ///// <summary> 238 ///// Calculates a set of plugins that directly or transitively depend on the plugin given in the argument. 239 ///// </summary> 240 ///// <param name="pluginInfo">The plugin the other depend on.</param> 241 ///// <returns>a list of plugins that are directly of transitively dependent.</returns> 242 //public List<PluginDescription> GetDependentPlugins(PluginDescription pluginInfo) { 243 // List<PluginDescription> mergedList = new List<PluginDescription>(); 244 // foreach (PluginDescription plugin in Plugins) { 245 // if (plugin.Dependencies.Contains(pluginInfo)) { 246 // if (!mergedList.Contains(plugin)) { 247 // mergedList.Add(plugin); 248 // } 249 // // for each of the dependent plugins add the list of transitively dependent plugins 250 // // make sure that only one entry for each plugin is added to the merged list 251 // foreach (PluginDescription dependentPlugin in GetDependentPlugins(plugin)) { 252 // if (!mergedList.Contains(dependentPlugin)) { 253 // mergedList.Add(dependentPlugin); 254 // } 255 // } 256 // } 257 // } 258 // return mergedList; 259 //} 260 261 private void NotifyListeners(string action, string entityName) { 134 private void FireAction(string action, object entity) { 262 135 if (Action != null) { 263 Action(this, new PluginInfrastructureEventArgs(action, entity Name));136 Action(this, new PluginInfrastructureEventArgs(action, entity)); 264 137 } 265 138 } -
branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs
r2495 r2497 54 54 this.Enabled = false; 55 55 56 pluginManager. Initialize();56 pluginManager.DiscoverAndCheckPlugins(); 57 57 58 58 applicationsListView.Items.Clear(); -
branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs
r2489 r2497 89 89 90 90 public void managerActionEventHandler(object sender, PluginInfrastructureEventArgs e) { 91 string info = e.Action + ": " + e.Entity Name;91 string info = e.Action + ": " + e.Entity; 92 92 //if (e.Action == PluginManagerAction.Initializing) info = "Initializing ..."; 93 93 //else if (e.Action == PluginManagerAction.PluginLoaded) info = "Loaded plugin " + e.Id + " ...";
Note: See TracChangeset
for help on using the changeset viewer.