Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/12/09 18:41:44 (15 years ago)
Author:
gkronber
Message:

Worked on plugin infrastructure events and the display in the SplashScreen. #799

Location:
branches/PluginInfrastructure Refactoring
Files:
1 deleted
6 edited
1 moved

Legend:

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

    r2488 r2489  
    3131namespace HeuristicLab.PluginInfrastructure.Manager {
    3232
    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
    3439    private List<IPluginDescription> plugins;
    3540    /// <summary>
     
    4853    }
    4954
    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    }
    5166
    5267    internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) {
     
    6277        foreach (var plugin in GetInstances<IPlugin>(desc)) {
    6378          plugin.OnLoad();
     79          FirePluginLoaded(plugin.Name);
    6480        }
    6581        desc.Load();
     
    85101
    86102    /// <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>
    87120    /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
    88121    /// </summary>
     
    134167    /// <returns>Enumerable of the discovered types.</returns>
    135168    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;
    140174    }
    141175
     
    152186    }
    153187
     188    private void FirePluginLoaded(string name) {
     189      if (PluginLoaded != null) PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", name));
     190    }
    154191
    155192    // infinite lease time
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj

    r2488 r2489  
    5454    <Compile Include="Loader.cs" />
    5555    <Compile Include="PluginDescription.cs" />
     56    <Compile Include="PluginInfrastructureEventArgs.cs" />
    5657    <Compile Include="PluginManager.cs" />
    57     <Compile Include="PluginManagerActionEventArgs.cs" />
    5858    <Compile Include="Properties\AssemblyInfo.cs" />
    5959  </ItemGroup>
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs

    r2488 r2489  
    3131namespace HeuristicLab.PluginInfrastructure.Manager {
    3232  internal class Loader : MarshalByRefObject {
    33     internal event PluginManagerActionEventHandler PluginAction;
     33    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
    3434
    3535    private Dictionary<PluginDescription, List<string>> pluginDependencies;
     
    163163          }
    164164        }
    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) {
    194170        }
    195171      }
     
    303279            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
    304280            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    }
    347287
    348288    // checks if all declared plugin files are actually available and disables plugins with missing files
     
    350290      foreach (PluginDescription desc in pluginDescriptions) {
    351291        if (!CheckPluginFiles(desc)) {
    352           //plugin.Message = "Disabled: missing plugin file.";
    353292          desc.Disable();
    354293        }
     
    359298      foreach (string filename in PluginDescription.Files) {
    360299        if (!File.Exists(filename)) {
    361           //if (MissingPluginFile != null) {
    362           //  MissingPluginFile(PluginDescription.Name, filename);
    363           //}
    364300          return false;
    365301        }
    366302      }
    367303      return true;
     304    }
     305
     306    private void FirePluginLoaded(string pluginName) {
     307      if (PluginLoaded != null)
     308        PluginLoaded(this, new PluginInfrastructureEventArgs("Plugin loaded", pluginName));
    368309    }
    369310
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginInfrastructureEventArgs.cs

    r2485 r2489  
    2424using System.Text;
    2525
    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>
     26namespace HeuristicLab.PluginInfrastructure {
     27  // to be replaced by GenericEventArgs
    4128  [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;
    6935    }
    7036  }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs

    r2488 r2489  
    3939    /// Event handler for actions in the plugin manager.
    4040    /// </summary>
    41     public event PluginManagerActionEventHandler Action;
     41    public event EventHandler<PluginInfrastructureEventArgs> Action;
    4242
    4343    private string pluginDir;
     
    9898    /// </summary>
    9999    public void Initialize() {
    100       NotifyListeners(PluginManagerAction.Initializing, "-");
     100      NotifyListeners("Initializing", "PluginInfrastructure");
    101101      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
    102102      setup.PrivateBinPath = pluginDir;
     
    104104      Loader remoteLoader = (Loader)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader");
    105105      remoteLoader.PluginDir = pluginDir;
    106       remoteLoader.PluginAction += 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
    107107      remoteLoader.Init();
    108       NotifyListeners(PluginManagerAction.Initialized, "-");
     108      NotifyListeners("Initialized", "PluginInfrastructure");
    109109
    110110      plugins = new List<PluginDescription>(remoteLoader.Plugins);
     
    144144      // and remotely tell it to start the application
    145145
    146       NotifyListeners(PluginManagerAction.ApplicationStart, appInfo.Name);
     146      NotifyListeners("Starting application", appInfo.Name);
    147147      AppDomain applicationDomain = null;
    148148      try {
     
    150150        setup.PrivateBinPath = pluginDir;
    151151        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); };
    155155        applicationManager.PrepareApplicationDomain(
    156156          new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
    157157          new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
    158         NotifyListeners(PluginManagerAction.Initialized, "All plugins");
     158        NotifyListeners("Started application", appInfo.Name);
    159159        applicationManager.Run(appInfo);
    160160      }
     
    259259    //}
    260260
    261     private void NotifyListeners(PluginManagerAction action, string text) {
     261    private void NotifyListeners(string action, string entityName) {
    262262      if (Action != null) {
    263         Action(this, new PluginManagerActionEventArgs(text, action));
     263        Action(this, new PluginInfrastructureEventArgs(action, entityName));
    264264      }
    265265    }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Interfaces/IApplicationManager.cs

    r2488 r2489  
    3434    IEnumerable<IApplicationDescription> Applications { get; }
    3535
     36    void LoadAssemblies(IEnumerable<byte[]> assemblies);
     37
    3638    IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class;
    3739    IEnumerable<T> GetInstances<T>() where T : class;
    38     IEnumerable<object> GetInstances(Type type);
    3940
    4041    IEnumerable<Type> GetTypes(Type type);
    4142    IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription);
    42     // IEnumerable<Type> GetTypes(Type type, Assembly assembly);
    4343  }
    4444}
  • branches/PluginInfrastructure Refactoring/HeuristicLab/SplashScreen.cs

    r2481 r2489  
    4747      infoLabel.Text = initialText;
    4848      this.manager = manager;
    49       manager.Action += new PluginManagerActionEventHandler(Manager_Action);
     49      manager.Action += managerActionEventHandler;
    5050      Assembly assembly = this.GetType().Assembly;
    5151      object[] attributes = assembly.GetCustomAttributes(false);
     
    8888    }
    8989
    90     public void Manager_Action(object sender, PluginManagerActionEventArgs e) {
    91       string info;
    92       if (e.Action == PluginManagerAction.Initializing) info = "Initializing ...";
    93       else if (e.Action == PluginManagerAction.PluginLoaded) info = "Loaded plugin " + e.Id + " ...";
    94       else if (e.Action == PluginManagerAction.Initialized) {
    95         info = "Initialization Completed";
    96         fadeTimer = new System.Timers.Timer();
    97         fadeTimer.SynchronizingObject = this;
    98         fadeTimer.Elapsed += new System.Timers.ElapsedEventHandler(fadeTimer_Elapsed);
    99         fadeTimer.Interval = initialInterval;
    100         fadeTimer.AutoReset = true;
    101         fadeTimer.Start();
    102       } else {
    103         if (e.Id != null) info = e.Action.ToString() + "   (" + e.Id + ")";
    104         else info = e.Action.ToString();
    105       }
     90    public void managerActionEventHandler(object sender, PluginInfrastructureEventArgs e) {
     91      string info = e.Action + ": " + e.EntityName;
     92      //if (e.Action == PluginManagerAction.Initializing) info = "Initializing ...";
     93      //else if (e.Action == PluginManagerAction.PluginLoaded) info = "Loaded plugin " + e.Id + " ...";
     94      //else if (e.Action == PluginManagerAction.Initialized) {
     95      //  info = "Initialization Completed";
     96      //  fadeTimer = new System.Timers.Timer();
     97      //  fadeTimer.SynchronizingObject = this;
     98      //  fadeTimer.Elapsed += new System.Timers.ElapsedEventHandler(fadeTimer_Elapsed);
     99      //  fadeTimer.Interval = initialInterval;
     100      //  fadeTimer.AutoReset = true;
     101      //  fadeTimer.Start();
     102      //} else {
     103      //  if (e.Id != null) info = e.Action.ToString() + "   (" + e.Id + ")";
     104      //  else info = e.Action.ToString();
     105      //}
    106106      SetInfoText(info);
    107107      Application.DoEvents();
     
    143143          closing = true;
    144144          if (fadeTimer != null) fadeTimer.Stop();
    145           manager.Action -= new PluginManagerActionEventHandler(this.Manager_Action); // remove event before calling close
     145          manager.Action -= managerActionEventHandler; // remove event before calling close
    146146          Application.DoEvents(); // work up all existing events
    147147          Close(); // close
Note: See TracChangeset for help on using the changeset viewer.