Changeset 2489 for branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager
- Timestamp:
- 11/12/09 18:41:44 (15 years ago)
- Location:
- branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager
- Files:
-
- 4 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationManager.cs
r2488 r2489 31 31 namespace HeuristicLab.PluginInfrastructure.Manager { 32 32 33 public class ApplicationManager : MarshalByRefObject, IApplicationManager { 33 public class DefaultApplicationManager : MarshalByRefObject, IApplicationManager { 34 internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded; 35 // cache for the AssemblyResolveEvent 36 // which must be handled when assemblies are loaded dynamically after the application start 37 private Dictionary<string, Assembly> loadedAssemblies; 38 34 39 private List<IPluginDescription> plugins; 35 40 /// <summary> … … 48 53 } 49 54 50 public ApplicationManager() : base() { } 55 public DefaultApplicationManager() 56 : base() { 57 loadedAssemblies = new Dictionary<string, Assembly>(); 58 // needed for the special case when assemblies are loaded dynamically via LoadAssemblies() 59 AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { 60 if (loadedAssemblies.ContainsKey(args.Name)) { 61 return loadedAssemblies[args.Name]; 62 } 63 return null; 64 }; 65 } 51 66 52 67 internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) { … … 62 77 foreach (var plugin in GetInstances<IPlugin>(desc)) { 63 78 plugin.OnLoad(); 79 FirePluginLoaded(plugin.Name); 64 80 } 65 81 desc.Load(); … … 85 101 86 102 /// <summary> 103 /// Loads assemblies dynamically from a byte array 104 /// </summary> 105 /// <param name="plugins">bytearray of all assemblies that should be loaded</param> 106 public void LoadAssemblies(IEnumerable<byte[]> assemblies) { 107 foreach (byte[] asm in assemblies) { 108 Assembly loadedAsm = Assembly.Load(asm); 109 RegisterLoadedAssembly(loadedAsm); 110 } 111 } 112 113 // register assembly in the assembly cache for the AssemblyResolveEvent 114 private void RegisterLoadedAssembly(Assembly asm) { 115 loadedAssemblies.Add(asm.FullName, asm); 116 loadedAssemblies.Add(asm.GetName().Name, asm); // add short name 117 } 118 119 /// <summary> 87 120 /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/> 88 121 /// </summary> … … 134 167 /// <returns>Enumerable of the discovered types.</returns> 135 168 public IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription) { 136 return from asm in AppDomain.CurrentDomain.GetAssemblies() 137 where pluginDescription.Assemblies.Contains(asm.Location) 138 from t in GetTypes(type, asm) 139 select t; 169 throw new NotImplementedException(); 170 //return from asm in AppDomain.CurrentDomain.GetAssemblies() 171 // where pluginDescription.Assemblies.Contains(asm.Location) 172 // from t in GetTypes(type, asm) 173 // select t; 140 174 } 141 175 … … 152 186 } 153 187 188 private void FirePluginLoaded(string name) { 189 if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", name)); 190 } 154 191 155 192 // infinite lease time -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj
r2488 r2489 54 54 <Compile Include="Loader.cs" /> 55 55 <Compile Include="PluginDescription.cs" /> 56 <Compile Include="PluginInfrastructureEventArgs.cs" /> 56 57 <Compile Include="PluginManager.cs" /> 57 <Compile Include="PluginManagerActionEventArgs.cs" />58 58 <Compile Include="Properties\AssemblyInfo.cs" /> 59 59 </ItemGroup> -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs
r2488 r2489 31 31 namespace HeuristicLab.PluginInfrastructure.Manager { 32 32 internal class Loader : MarshalByRefObject { 33 internal event PluginManagerActionEventHandler PluginAction;33 internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded; 34 34 35 35 private Dictionary<PluginDescription, List<string>> pluginDependencies; … … 163 163 } 164 164 } 165 catch (FileNotFoundException ex) { 166 //PluginDescription info = new PluginDescription(); 167 //AssemblyName name = assembly.GetName(); 168 //info.Name = name.Name; 169 //info.Version = name.Version; 170 //info.Assemblies.Add(assembly.FullName); 171 //info.Files.Add(assembly.Location); 172 //info.Message = "File not found: " + ex.FileName; 173 //disabledPlugins.Add(info); 174 } 175 catch (FileLoadException ex) { 176 //PluginDescription info = new PluginDescription(); 177 //AssemblyName name = assembly.GetName(); 178 //info.Name = name.Name; 179 //info.Version = name.Version; 180 //info.Files.Add(assembly.Location); 181 //info.Assemblies.Add(assembly.FullName); 182 //info.Message = "Couldn't load file: " + ex.FileName; 183 //disabledPlugins.Add(info); 184 } 185 catch (InvalidPluginException ex) { 186 //PluginDescription info = new PluginDescription(); 187 //AssemblyName name = assembly.GetName(); 188 //info.Name = name.Name; 189 //info.Version = name.Version; 190 //info.Files.Add(assembly.Location); 191 //info.Assemblies.Add(assembly.FullName); 192 //info.Message = "Couldn't load plugin class from assembly: " + assembly.GetName().Name + ". Necessary plugin attributes are missing."; 193 //disabledPlugins.Add(info); 165 catch (FileNotFoundException) { 166 } 167 catch (FileLoadException) { 168 } 169 catch (InvalidPluginException) { 194 170 } 195 171 } … … 303 279 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); 304 280 plugin.OnLoad(); 305 desc.Load(); 306 PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded)); 307 } 308 } 309 } 310 } 311 //private PluginDescription GetPluginDescription(IPlugin plugin) { 312 // if (PluginDescriptions.ContainsKey(plugin)) { 313 // return PluginDescriptions[plugin]; 314 // } 315 // // store the data of the plugin in a description file which can be used without loading the plugin assemblies 316 // PluginDescription PluginDescription = new PluginDescription(); 317 // PluginDescription.Name = plugin.Name; 318 // PluginDescription.Version = plugin.Version; 319 320 // object[] customAttributes = plugin.GetType().Assembly.GetCustomAttributes(typeof(AssemblyBuildDateAttribute), false); 321 // if (customAttributes.Length > 0) { 322 // PluginDescription.BuildDate = ((AssemblyBuildDateAttribute)customAttributes[0]).BuildDate; 323 // } 324 325 // string baseDir = AppDomain.CurrentDomain.BaseDirectory; 326 327 // Array.ForEach<string>(plugin.FileNames, delegate(string file) { 328 // string filename = pluginDir + "/" + file; 329 // // always use \ as the directory separator 330 // PluginDescription.Files.Add(filename.Replace('/', '\\')); 331 // }); 332 333 // PluginDescription preloadedInfo = preloadedPluginDescriptions.Find(delegate(PluginDescription info) { return info.Name == plugin.Name; }); 334 // foreach (string assembly in preloadedInfo.Assemblies) { 335 // // always use \ as directory separator (this is necessary for discovery of types in 336 // // plugins see DiscoveryService.GetTypes() 337 // PluginDescription.Assemblies.Add(assembly.Replace('/', '\\')); 338 // } 339 // foreach (string dependency in pluginDependencies[preloadedInfo]) { 340 // // accumulate the dependencies of each assembly into the dependencies of the whole plugin 341 // PluginDescription dependencyInfo = GetPluginDescription(pluginsByName[dependency]); 342 // PluginDescription.Dependencies.Add(dependencyInfo); 343 // } 344 // PluginDescriptions[plugin] = PluginDescription; 345 // return PluginDescription; 346 //} 281 FirePluginLoaded(plugin.Name); 282 } 283 } 284 desc.Load(); 285 } 286 } 347 287 348 288 // checks if all declared plugin files are actually available and disables plugins with missing files … … 350 290 foreach (PluginDescription desc in pluginDescriptions) { 351 291 if (!CheckPluginFiles(desc)) { 352 //plugin.Message = "Disabled: missing plugin file.";353 292 desc.Disable(); 354 293 } … … 359 298 foreach (string filename in PluginDescription.Files) { 360 299 if (!File.Exists(filename)) { 361 //if (MissingPluginFile != null) {362 // MissingPluginFile(PluginDescription.Name, filename);363 //}364 300 return false; 365 301 } 366 302 } 367 303 return true; 304 } 305 306 private void FirePluginLoaded(string pluginName) { 307 if (PluginLoaded != null) 308 PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", pluginName)); 368 309 } 369 310 -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs
r2485 r2489 24 24 using System.Text; 25 25 26 namespace HeuristicLab.PluginInfrastructure.Manager { 27 public enum PluginManagerAction { Initializing, PluginLoaded, ApplicationStart, Initialized } 28 29 30 /// <summary> 31 /// Event handler for all action events of the plugin manager. 32 /// </summary> 33 /// <param name="sender">The sender of the action event.</param> 34 /// <param name="e">The event arguments.</param> 35 public delegate void PluginManagerActionEventHandler(object sender, PluginManagerActionEventArgs e); 36 37 // this class must be serializable because EventArgs are transmitted over AppDomain boundaries 38 /// <summary> 39 /// Class for the event arguments of plugin manager action events. 40 /// </summary> 26 namespace HeuristicLab.PluginInfrastructure { 27 // to be replaced by GenericEventArgs 41 28 [Serializable] 42 public class PluginManagerActionEventArgs { 43 private PluginManagerAction action; 44 /// <summary> 45 /// Gets or sets the action that has been performed. 46 /// </summary> 47 public PluginManagerAction Action { 48 get { return action; } 49 set { this.action = value; } 50 } 51 private string id; 52 /// <summary> 53 /// Gets or sets the id of the action event arguments. 54 /// </summary> 55 public string Id { 56 get { return id; } 57 set { id = value; } 58 } 59 60 /// <summary> 61 /// Initializes a new instance of <see cref="PluginManagerActionEventArgs"/> with the given 62 /// <paramref name="id"/> and <paramref name="action"/>. 63 /// </summary> 64 /// <param name="id">The id of the action event arguments.</param> 65 /// <param name="action">The action of the plugin manager.</param> 66 public PluginManagerActionEventArgs(string id, PluginManagerAction action) { 67 this.Id = id; 68 this.Action = action; 29 public class PluginInfrastructureEventArgs : EventArgs { 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; 69 35 } 70 36 } -
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs
r2488 r2489 39 39 /// Event handler for actions in the plugin manager. 40 40 /// </summary> 41 public event PluginManagerActionEventHandlerAction;41 public event EventHandler<PluginInfrastructureEventArgs> Action; 42 42 43 43 private string pluginDir; … … 98 98 /// </summary> 99 99 public void Initialize() { 100 NotifyListeners( PluginManagerAction.Initializing, "-");100 NotifyListeners("Initializing", "PluginInfrastructure"); 101 101 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; 102 102 setup.PrivateBinPath = pluginDir; … … 104 104 Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader"); 105 105 remoteLoader.PluginDir = pluginDir; 106 remoteLoader.Plugin Action += delegate(object sender, PluginManagerActionEventArgs args) { if (Action != null) Action(this, args); };106 remoteLoader.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); }; // forward all events from the remoteLoader to listeners 107 107 remoteLoader.Init(); 108 NotifyListeners( PluginManagerAction.Initialized, "-");108 NotifyListeners("Initialized", "PluginInfrastructure"); 109 109 110 110 plugins = new List<PluginDescription>(remoteLoader.Plugins); … … 144 144 // and remotely tell it to start the application 145 145 146 NotifyListeners( PluginManagerAction.ApplicationStart, appInfo.Name);146 NotifyListeners("Starting application", appInfo.Name); 147 147 AppDomain applicationDomain = null; 148 148 try { … … 150 150 setup.PrivateBinPath = pluginDir; 151 151 applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup); 152 ApplicationManager applicationManager =153 ( ApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.ApplicationManager");154 //applicationManager.PluginAction += delegate(object sender, PluginManagerActionEventArgs args) { if (Action != null) Action(this, args); };152 DefaultApplicationManager applicationManager = 153 (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager"); 154 applicationManager.PluginLoaded += delegate(object sender, PluginInfrastructureEventArgs args) { NotifyListeners(args.Action, args.EntityName); }; 155 155 applicationManager.PrepareApplicationDomain( 156 156 new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()), 157 157 new List<IPluginDescription>(plugins.Cast<IPluginDescription>())); 158 NotifyListeners( PluginManagerAction.Initialized, "All plugins");158 NotifyListeners("Started application", appInfo.Name); 159 159 applicationManager.Run(appInfo); 160 160 } … … 259 259 //} 260 260 261 private void NotifyListeners( PluginManagerAction action, string text) {261 private void NotifyListeners(string action, string entityName) { 262 262 if (Action != null) { 263 Action(this, new Plugin ManagerActionEventArgs(text, action));263 Action(this, new PluginInfrastructureEventArgs(action, entityName)); 264 264 } 265 265 }
Note: See TracChangeset
for help on using the changeset viewer.