Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/18/09 18:33:30 (15 years ago)
Author:
gkronber
Message:

Worked on core of plugin infrastructure.

  • Collected all classes into a single assembly (HL.PluginInfrastructure)
  • Moved SplashScreen and MainForm from HeuristicLab.exe project into the plugin infrastructure.
  • Introduced namespaces
  • Added strict access modifiers (internal)
  • Fixed most FxCop warnings in plugin infrastructure core.
  • Fixed issues with plugin load/unload events
  • Deleted empty interface IControl

#799

Location:
branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager
Files:
6 moved

Legend:

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

    r2503 r2504  
    2929  /// </summary>
    3030  [Serializable]
    31   public class ApplicationDescription : IApplicationDescription {
     31  internal sealed class ApplicationDescription : IApplicationDescription {
    3232    private string name;
    3333
     
    4444    /// Gets or sets the version of the application.
    4545    /// </summary>
    46     public Version Version {
     46    internal Version Version {
    4747      get { return version; }
    4848      set { version = value; }
     
    6262    /// Gets or sets the boolean flag if the application should be automatically restarted.
    6363    /// </summary>
    64     public bool AutoRestart {
     64    internal bool AutoRestart {
    6565      get { return autoRestart; }
    6666      set { autoRestart = value; }
     
    7171    /// Gets or sets the name of the assembly that contains the IApplication type.
    7272    /// </summary>
    73     public string DeclaringAssemblyName {
     73    internal string DeclaringAssemblyName {
    7474      get { return declaringAssemblyName; }
    7575      set { declaringAssemblyName = value; }
     
    8080    /// Gets or sets the name of the type that implements the interface IApplication.
    8181    /// </summary>
    82     public string DeclaringTypeName {
     82    internal string DeclaringTypeName {
    8383      get { return declaringTypeName; }
    8484      set { declaringTypeName = value; }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/DefaultApplicationManager.cs

    r2503 r2504  
    3232namespace HeuristicLab.PluginInfrastructure.Manager {
    3333
    34   public sealed class DefaultApplicationManager : MarshalByRefObject, IApplicationManager {
     34  internal sealed class DefaultApplicationManager : MarshalByRefObject, IApplicationManager {
    3535    internal event EventHandler<PluginInfrastructureEventArgs> PluginLoaded;
    3636    internal event EventHandler<PluginInfrastructureEventArgs> PluginUnloaded;
     
    4242    private List<IPlugin> loadedPlugins;
    4343
    44     private List<IPluginDescription> plugins;
     44    private List<PluginDescription> plugins;
    4545    /// <summary>
    4646    /// Gets all plugins.
    4747    /// </summary>
    4848    public IEnumerable<IPluginDescription> Plugins {
    49       get { return plugins; }
    50       internal set { plugins = new List<IPluginDescription>(value); }
    51     }
    52 
    53     private List<IApplicationDescription> applications;
     49      get { return plugins.Cast<IPluginDescription>(); }
     50    }
     51
     52    private List<ApplicationDescription> applications;
    5453    /// <summary>
    5554    /// Gets all installed applications.
    5655    /// </summary>
    5756    public IEnumerable<IApplicationDescription> Applications {
    58       get { return applications; }
     57      get { return applications.Cast<IApplicationDescription>(); }
    5958    }
    6059
     
    7271    }
    7372
    74     internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) {
    75       this.plugins = new List<IPluginDescription>(plugins);
    76       this.applications = new List<IApplicationDescription>(apps);
     73    internal void PrepareApplicationDomain(IEnumerable<ApplicationDescription> apps, IEnumerable<PluginDescription> plugins) {
     74      this.plugins = new List<PluginDescription>(plugins);
     75      this.applications = new List<ApplicationDescription>(apps);
    7776      PluginInfrastructure.ApplicationManager.RegisterApplicationManager(this);
    7877      LoadPlugins(plugins);
    7978    }
    8079
    81     private void LoadPlugins(IEnumerable<IPluginDescription> plugins) {
     80    private void LoadPlugins(IEnumerable<PluginDescription> plugins) {
    8281      // load all loadable plugins (all dependencies available) into the execution context
    8382      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
     
    9695    }
    9796
    98     internal void Run(IApplicationDescription appInfo) {
     97    internal void Run(ApplicationDescription appInfo) {
    9998      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
    10099      try {
    101100        runnablePlugin.Run();
    102       }
    103       catch (Exception e) {
    104         throw new Exception(String.Format(
    105           "Unexpected exception caught: \"{0}\"\r\n" +
    106           "Type: {1}\r\n" +
    107           "Plugin {2}:\r\n{3}",
    108           e.Message,
    109           e.GetType().FullName,
    110           appInfo.Name,
    111           e.ToString()));
    112101      }
    113102      finally {
     
    156145    /// <param name="asm">Declaring assembly.</param>
    157146    /// <returns>Enumerable of the created instances.</returns>
    158     public IEnumerable<T> GetInstances<T>(Assembly asm) where T : class {
     147    private static IEnumerable<T> GetInstances<T>(Assembly asm) where T : class {
    159148      return from t in GetTypes(typeof(T), asm)
    160149             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
     
    201190    /// <returns>Enumerable of the discovered types.</returns>
    202191    public IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription) {
     192      PluginDescription pluginDesc = (PluginDescription)pluginDescription;
    203193      return from asm in AppDomain.CurrentDomain.GetAssemblies()
    204              where pluginDescription.Assemblies.Any(asmPath => Path.GetFullPath(asmPath) == Path.GetFullPath(asm.Location))
     194             where pluginDesc.Assemblies.Any(asmPath => Path.GetFullPath(asmPath) == Path.GetFullPath(asm.Location))
    205195             from t in GetTypes(type, asm)
    206196             select t;
     
    213203    /// <param name="assembly">Assembly that should be searched for types.</param>
    214204    /// <returns>Enumerable of the discovered types.</returns>
    215     private IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
     205    private static IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
    216206      return from t in assembly.GetTypes()
    217207             where type.IsAssignableFrom(t)
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginDescription.cs

    r2503 r2504  
    3030  /// </summary>
    3131  [Serializable]
    32   public class PluginDescription : IPluginDescription {
     32  internal sealed class PluginDescription : IPluginDescription {
     33    private int nTimesLoaded;
     34
    3335    private string name;
    3436    /// <summary>
     
    3739    public string Name {
    3840      get { return name; }
    39       set { name = value; }
     41      internal set { name = value; }
    4042    }
    4143    private Version version;
     
    4345    /// Gets or sets the version of the plugin.
    4446    /// </summary>
    45     public Version Version {
     47    internal Version Version {
    4648      get { return version; }
    4749      set { version = value; }
     
    5153    /// Gets or sets the build date of the plugin.
    5254    /// </summary>
    53     public DateTime BuildDate {
     55    internal DateTime BuildDate {
    5456      get { return buildDate; }
    5557      set { buildDate = value; }
     
    6466    }
    6567
    66     private int nTimesLoaded;
    67     public void Disable() {
    68       if (pluginState != PluginState.Undefined)
    69         throw new InvalidOperationException("Can't disabled a plugin in state " + pluginState);
    70       pluginState = PluginState.Disabled;
    71     }
    72 
    73     public void Enable() {
    74       if (pluginState != PluginState.Undefined)
    75         throw new InvalidOperationException("Can't enabled a plugin in state " + pluginState);
    76       pluginState = PluginState.Enabled;
    77     }
    78 
    79     public void Load() {
    80       if (!(pluginState == PluginState.Enabled || pluginState == PluginState.Loaded))
    81         throw new InvalidOperationException("Can't loaded a plugin in state " + pluginState);
    82       pluginState = PluginState.Loaded;
    83       nTimesLoaded++;
    84     }
    85 
    86     public void Unload() {
    87       if (pluginState != PluginState.Loaded)
    88         throw new InvalidOperationException("Can't unload a plugin in state " + pluginState);
    89       nTimesLoaded--;
    90       if (nTimesLoaded == 0) pluginState = PluginState.Enabled;
    91     }
    9268
    9369    private List<string> files = new List<string>();
     
    9672    /// These files are deleted when the plugin is removed or updated.
    9773    /// </summary>
    98     public IEnumerable<string> Files {
     74    internal IEnumerable<string> Files {
    9975      get { return files; }
    10076    }
     
    10480    }
    10581
    106     private List<IPluginDescription> dependencies = new List<IPluginDescription>();
     82    private List<PluginDescription> dependencies = new List<PluginDescription>();
    10783    /// <summary>
    10884    /// Gets all dependencies of the plugin.
    10985    /// </summary>
    110     public IEnumerable<IPluginDescription> Dependencies {
     86    internal IEnumerable<PluginDescription> Dependencies {
    11187      get { return dependencies; }
    11288    }
    11389
    114     public void AddDependency(PluginDescription dependency) {
     90    internal void AddDependency(PluginDescription dependency) {
    11591      dependencies.Add(dependency);
    11692    }
     
    12197    /// Gets the names of the assemblies that belong to this plugin.
    12298    /// </summary>
    123     public IEnumerable<string> Assemblies {
     99    internal IEnumerable<string> Assemblies {
    124100      get { return assemblies; }
    125101      // set { assemblies = value; }
     
    130106    }
    131107
    132     public PluginDescription() {
    133       nTimesLoaded = 0;
     108    internal PluginDescription() {
    134109      pluginState = PluginState.Undefined;
    135110    }
     111
     112    internal void Disable() {
     113      if (pluginState != PluginState.Undefined)
     114        throw new InvalidOperationException("Can't disabled a plugin in state " + pluginState);
     115      pluginState = PluginState.Disabled;
     116    }
     117
     118    internal void Enable() {
     119      if (pluginState != PluginState.Undefined)
     120        throw new InvalidOperationException("Can't enabled a plugin in state " + pluginState);
     121      pluginState = PluginState.Enabled;
     122    }
     123
     124    internal void Load() {
     125      if (!(pluginState == PluginState.Enabled || pluginState == PluginState.Loaded))
     126        throw new InvalidOperationException("Can't loaded a plugin in state " + pluginState);
     127      pluginState = PluginState.Loaded;
     128      nTimesLoaded++;
     129    }
     130
     131    internal void Unload() {
     132      if (pluginState != PluginState.Loaded)
     133        throw new InvalidOperationException("Can't unload a plugin in state " + pluginState);
     134      nTimesLoaded--;
     135      if (nTimesLoaded == 0) pluginState = PluginState.Enabled;
     136    }
     137
    136138
    137139    /// <summary>
     
    151153    /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns>
    152154    public override bool Equals(object obj) {
    153       if (!(obj is PluginDescription))
    154         return false;
    155       PluginDescription other = (PluginDescription)obj;
     155      PluginDescription other = obj as PluginDescription;
     156      if (other == null) return false;
    156157
    157158      return other.Name == this.Name && other.Version == this.Version;
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginInfrastructureEventArgs.cs

    r2503 r2504  
    2727  // to be replaced by GenericEventArgs
    2828  [Serializable]
    29   public class PluginInfrastructureEventArgs : EventArgs {
    30     public string Action { get; private set; }
    31     public object Entity { get; private set; }
    32     public PluginInfrastructureEventArgs(string action, object entity) {
     29  internal sealed class PluginInfrastructureEventArgs : EventArgs {
     30    internal string Action { get; private set; }
     31    internal object Entity { get; private set; }
     32    internal PluginInfrastructureEventArgs(string action, object entity) {
    3333      this.Action = action;
    3434      this.Entity = entity;
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginManager.cs

    r2503 r2504  
    3535  /// Class to manage different plugins.
    3636  /// </summary>
    37   public sealed class PluginManager : MarshalByRefObject {
     37  internal sealed class PluginManager : MarshalByRefObject {
    3838    /// <summary>
    3939    /// Event handler for actions in the plugin manager.
    4040    /// </summary>
    41     public event EventHandler<PluginInfrastructureEventArgs> Action;
     41    internal event EventHandler<PluginInfrastructureEventArgs> Action;
    4242
    4343    private string pluginDir;
     
    4949    /// Gets all installed applications.
    5050    /// </summary>
    51     public IEnumerable<ApplicationDescription> Applications {
     51    internal IEnumerable<ApplicationDescription> Applications {
    5252      get { return applications; }
    5353    }
     
    5656    private bool initialized;
    5757
    58     public PluginManager(string pluginDir) {
     58    internal PluginManager(string pluginDir) {
    5959      this.pluginDir = pluginDir;
    6060      plugins = new List<PluginDescription>();
     
    6363    }
    6464
    65     public void Reset() {
     65    internal void Reset() {
    6666      initialized = false;
    6767      if (plugins != null && plugins.Any(x => x.PluginState == PluginState.Loaded)) throw new InvalidOperationException("Reset() is not allowed while applications are active.");
     
    7373    /// Determines installed plugins and checks if all plugins are loadable.
    7474    /// </summary>
    75     public void DiscoverAndCheckPlugins() {
     75    internal void DiscoverAndCheckPlugins() {
    7676      OnAction(new PluginInfrastructureEventArgs("Initializing", "PluginInfrastructure"));
    7777      AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
     
    8080      try {
    8181        pluginDomain = AppDomain.CreateDomain("plugin domain", null, setup);
    82         PluginValidator remoteValidator = (PluginValidator)pluginDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.Loader");
     82        Type pluginValidatorType = typeof(PluginValidator);
     83        PluginValidator remoteValidator = (PluginValidator)pluginDomain.CreateInstanceAndUnwrap(pluginValidatorType.Assembly.FullName, pluginValidatorType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null);
    8384        remoteValidator.PluginDir = pluginDir;
    8485        // forward all events from the remoteValidator to listeners
     
    109110    /// </summary>
    110111    /// <param name="appInfo">application to run</param>
    111     public void Run(ApplicationDescription appInfo) {
     112    internal void Run(ApplicationDescription appInfo) {
    112113      if (!initialized) throw new InvalidOperationException("PluginManager is not initialized. DiscoverAndCheckPlugins() must be called before Run()");
    113114      // create a separate AppDomain for the application
     
    121122        setup.PrivateBinPath = pluginDir;
    122123        applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup);
     124        Type applicationManagerType = typeof(DefaultApplicationManager);
    123125        DefaultApplicationManager applicationManager =
    124           (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap("HeuristicLab.PluginInfraStructure.Manager", "HeuristicLab.PluginInfrastructure.Manager.DefaultApplicationManager");
     126          (DefaultApplicationManager)applicationDomain.CreateInstanceAndUnwrap(applicationManagerType.Assembly.FullName, applicationManagerType.FullName, true, BindingFlags.NonPublic | BindingFlags.Instance, null, null, null, null, null);
    125127        applicationManager.PluginLoaded += applicationManager_PluginLoaded;
    126128        applicationManager.PluginUnloaded += applicationManager_PluginUnloaded;
    127         applicationManager.PrepareApplicationDomain(
    128           new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
    129           new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
     129        applicationManager.PrepareApplicationDomain(applications, plugins);
    130130        OnAction(new PluginInfrastructureEventArgs("Started application", appInfo));
    131131        applicationManager.Run(appInfo);
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2503 r2504  
    5757    }
    5858
    59     public string PluginDir { get; set; }
    60 
    61     public PluginValidator() {
     59    internal string PluginDir { get; set; }
     60
     61    internal PluginValidator() {
    6262      this.pluginDependencies = new Dictionary<PluginDescription, List<string>>();
    6363
     
    114114
    115115      foreach (IApplication application in GetApplications()) {
     116        Type appType = application.GetType();
     117        ApplicationAttribute attr = (from x in appType.GetCustomAttributes(typeof(ApplicationAttribute), false)
     118                                     select (ApplicationAttribute)x).Single();
    116119        ApplicationDescription info = new ApplicationDescription();
    117120        info.Name = application.Name;
    118         info.Version = application.Version;
     121        info.Version = appType.Assembly.GetName().Version;
    119122        info.Description = application.Description;
    120         info.AutoRestart = application.RestartOnErrors;
    121         info.DeclaringAssemblyName = application.GetType().Assembly.GetName().Name;
    122         info.DeclaringTypeName = application.GetType().Namespace + "." + application.GetType().Name;
     123        info.AutoRestart = attr.RestartOnErrors;
     124        info.DeclaringAssemblyName = appType.Assembly.GetName().Name;
     125        info.DeclaringTypeName = appType.Namespace + "." + application.GetType().Name;
    123126
    124127        applications.Add(info);
     
    126129    }
    127130
    128     private IEnumerable<IApplication> GetApplications() {
     131    private static IEnumerable<IApplication> GetApplications() {
    129132      return from asm in AppDomain.CurrentDomain.GetAssemblies()
    130133             from t in asm.GetTypes()
     
    206209      }
    207210
     211      var buildDates = from attr in CustomAttributeData.GetCustomAttributes(pluginType.Assembly)
     212                       where IsAttributeDataForType(attr, typeof(AssemblyBuildDateAttribute))
     213                       select (string)attr.ConstructorArguments[0].Value;
     214
    208215      // minimal sanity check of the attribute values
    209216      if (!string.IsNullOrEmpty(pluginName) &&
    210217          pluginFiles.Count > 0 &&
    211           pluginAssemblies.Count > 0) {
     218          pluginAssemblies.Count > 0 &&
     219          buildDates.Count() == 1) {
    212220        // create a temporary PluginDescription that contains the attribute values
    213221        PluginDescription info = new PluginDescription();
    214222        info.Name = pluginName;
    215223        info.Version = pluginType.Assembly.GetName().Version;
     224        info.BuildDate = DateTime.Parse(buildDates.Single(), System.Globalization.CultureInfo.InvariantCulture);
    216225        info.AddAssemblies(pluginAssemblies);
    217226        info.AddFiles(pluginFiles);
     
    224233    }
    225234
    226     private bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) {
     235    private static bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) {
    227236      return attributeData.Constructor.DeclaringType.AssemblyQualifiedName == attributeType.AssemblyQualifiedName;
    228237    }
     
    266275      // load all loadable plugins (all dependencies available) into the execution context
    267276      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions
    268                                                                                 .Cast<IPluginDescription>()
    269277                                                                                .Where(x => x.PluginState != PluginState.Disabled))) {
    270278        List<Type> types = new List<Type>();
     
    290298
    291299    // checks if all declared plugin files are actually available and disables plugins with missing files
    292     private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
     300    private static void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
    293301      foreach (PluginDescription desc in pluginDescriptions) {
    294302        if (!CheckPluginFiles(desc)) {
     
    298306    }
    299307
    300     private bool CheckPluginFiles(PluginDescription PluginDescription) {
    301       foreach (string filename in PluginDescription.Files) {
     308    private static bool CheckPluginFiles(PluginDescription pluginDescription) {
     309      foreach (string filename in pluginDescription.Files) {
    302310        if (!File.Exists(filename)) {
    303311          return false;
Note: See TracChangeset for help on using the changeset viewer.