Changeset 1228


Ignore:
Timestamp:
02/26/09 13:40:08 (11 years ago)
Author:
gkronber
Message:

Implemented #471 (OnLoad hook for plugins).

Location:
branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs

    r8 r1228  
    3030  /// Default implementation of the IPlugin interface.
    3131  /// </summary>
    32   public class PluginBase : IPlugin {
     32  public abstract class PluginBase : IPlugin {
    3333    private string name;
    3434    private Version version;
     
    4444
    4545      // exactly one attribute of the type ClassInfoAttribute must be given
    46       if(pluginAttributes.Length != 1) {
     46      if (pluginAttributes.Length != 1) {
    4747        throw new InvalidPluginException();
    4848      }
     
    5252
    5353      // if the plugin name is not explicitly set in the attribute then the default plugin name is the FullName of the type
    54       if(pluginAttribute != null && pluginAttribute.Name != null) {
     54      if (pluginAttribute != null && pluginAttribute.Name != null) {
    5555        this.name = pluginAttribute.Name;
    5656      } else {
     
    5959
    6060      // if the version is not explicitly set in the attribute then the version of the assembly is used as default
    61       if(pluginAttribute != null && pluginAttribute.Version != null) {
     61      if (pluginAttribute != null && pluginAttribute.Version != null) {
    6262        this.version = new Version(pluginAttribute.Version);
    6363      } else {
     
    6666
    6767      // if the description is not explicitly set in the attribute then the name of name of the plugin is used as default
    68       if(pluginAttribute != null && pluginAttribute.Description != null) {
     68      if (pluginAttribute != null && pluginAttribute.Description != null) {
    6969        this.description = pluginAttribute.Description;
    7070      } else {
     
    7878      this.files = new string[fileAttributes.Length];
    7979      int i = 0;
    80       foreach(PluginFileAttribute fileAttr in fileAttributes) {
     80      foreach (PluginFileAttribute fileAttr in fileAttributes) {
    8181        files[i++] = fileAttr.Filename;
    8282      }
     
    102102    }
    103103
    104     public  string[] Files {
     104    public string[] Files {
    105105      get {
    106106        return files;
     
    108108    }
    109109
    110     public virtual void OnInstall() {
    111     }
    112 
    113     public virtual void OnDelete() {
    114     }
    115 
    116     public virtual void OnPreUpdate() {
    117     }
    118 
    119     public virtual void OnPostUpdate() {
    120     }
     110    public virtual void OnLoad() { }
     111    public virtual void OnInstall() { }
     112    public virtual void OnDelete() { }
     113    public virtual void OnPreUpdate() { }
     114    public virtual void OnPostUpdate() { }
    121115
    122116    #endregion
  • branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Interfaces/IPlugin.cs

    r2 r1228  
    3030  /// assemblies of the plugin. Plugin developers can use the properties of this interface to store
    3131  /// plugin data (name, version, files, update location ...).
    32   /// The methods OnInstall(), OnDelete(), OnPreUpdate(), OnPostUpdate() are called by the framework
     32  /// The methods OnLoad(), OnInstall(), OnDelete(), OnPreUpdate(), OnPostUpdate() are called by the framework
    3333  /// when the corresponding actions are executed. This mechanism allows that the plugin reacts to such
    3434  /// events. For instance to store plugin specific settings.
     
    4242    string[] Files { get; }
    4343
     44
     45    /// <summary>
     46    /// Called by the framework whenever the plugin is loaded.
     47    /// Plugins are loaded once at startup and then each time a new application is started from the starter.
     48    /// </summary>
     49    void OnLoad();
    4450    /// <summary>
    4551    /// called by the framework after the plugin was successfully installed
  • branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Loader.cs

    r535 r1228  
    4646      get {
    4747        List<PluginInfo> list = new List<PluginInfo>();
    48         foreach(PluginInfo info in allPlugins.Keys) {
    49           if(!disabledPlugins.Exists(delegate(PluginInfo disabledInfo) { return info.Name == disabledInfo.Name; })) {
     48        foreach (PluginInfo info in allPlugins.Keys) {
     49          if (!disabledPlugins.Exists(delegate(PluginInfo disabledInfo) { return info.Name == disabledInfo.Name; })) {
    5050            list.Add(info);
    5151          }
     
    7575
    7676    private IPlugin FindPlugin(PluginInfo plugin) {
    77       if(allPlugins.ContainsKey(plugin)) {
     77      if (allPlugins.ContainsKey(plugin)) {
    7878        return allPlugins[plugin];
    7979      } else return null;
     
    9595        try {
    9696          return Assembly.ReflectionOnlyLoad(args.Name);
    97         } catch(FileLoadException ex) {
     97        }
     98        catch (FileLoadException ex) {
    9899          return null;
    99100        }
    100         };
     101      };
    101102      allPlugins.Clear();
    102103      disabledPlugins.Clear();
     
    115116      applications = new List<ApplicationInfo>();
    116117
    117       foreach(IApplication application in apps) {
     118      foreach (IApplication application in apps) {
    118119        ApplicationInfo info = new ApplicationInfo();
    119120        info.Name = application.Name;
     
    131132      List<Assembly> assemblies = new List<Assembly>();
    132133      // load all installed plugins into the reflection only context
    133       foreach(String filename in Directory.GetFiles(pluginDir, "*.dll")) {
     134      foreach (String filename in Directory.GetFiles(pluginDir, "*.dll")) {
    134135        try {
    135136          assemblies.Add(ReflectionOnlyLoadDll(filename));
    136         } catch(BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll
     137        }
     138        catch (BadImageFormatException) { } // just ignore the case that the .dll file is not actually a CLR dll
    137139      }
    138140      return assemblies;
     
    144146
    145147    private void CheckAssemblyDependencies(List<Assembly> assemblies) {
    146       foreach(Assembly assembly in assemblies) {
     148      foreach (Assembly assembly in assemblies) {
    147149        // GetExportedTypes throws FileNotFoundException when a referenced assembly
    148150        // of the current assembly is missing.
     
    150152          Type[] exported = assembly.GetExportedTypes();
    151153
    152           foreach(Type t in exported) {
     154          foreach (Type t in exported) {
    153155            // if there is a type that implements IPlugin
    154             if(Array.Exists<Type>(t.GetInterfaces(), delegate(Type iface) {
     156            if (Array.Exists<Type>(t.GetInterfaces(), delegate(Type iface) {
    155157              // use AssemblyQualifiedName to compare the types because we can't directly
    156158              // compare ReflectionOnly types and Execution types
     
    161163            }
    162164          }
    163         } catch(FileNotFoundException ex) {
     165        }
     166        catch (FileNotFoundException ex) {
    164167          PluginInfo info = new PluginInfo();
    165168          AssemblyName name = assembly.GetName();
     
    170173          info.Message = "File not found: " + ex.FileName;
    171174          disabledPlugins.Add(info);
    172         } catch(FileLoadException ex) {
     175        }
     176        catch (FileLoadException ex) {
    173177          PluginInfo info = new PluginInfo();
    174178          AssemblyName name = assembly.GetName();
     
    197201      string pluginName = "";
    198202      // iterate through all custom attributes and search for named arguments that we are interested in
    199       foreach(CustomAttributeData attributeData in attributes) {
     203      foreach (CustomAttributeData attributeData in attributes) {
    200204        List<CustomAttributeNamedArgument> namedArguments = new List<CustomAttributeNamedArgument>(attributeData.NamedArguments);
    201205        // if the current attribute contains a named argument with the name "Name" then extract the plugin name
     
    203207          return arg.MemberInfo.Name == "Name";
    204208        });
    205         if(pluginNameArgument.MemberInfo != null) {
     209        if (pluginNameArgument.MemberInfo != null) {
    206210          pluginName = (string)pluginNameArgument.TypedValue.Value;
    207211        }
     
    211215          return arg.MemberInfo.Name == "Dependency";
    212216        });
    213         if(dependencyNameArgument.MemberInfo != null) {
     217        if (dependencyNameArgument.MemberInfo != null) {
    214218          pluginDependencies.Add((string)dependencyNameArgument.TypedValue.Value);
    215219        }
     
    222226          return arg.MemberInfo.Name == "Filetype";
    223227        });
    224         if(filenameArg.MemberInfo != null && filetypeArg.MemberInfo != null) {
     228        if (filenameArg.MemberInfo != null && filetypeArg.MemberInfo != null) {
    225229          pluginFiles.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value);
    226           if((PluginFileType)filetypeArg.TypedValue.Value == PluginFileType.Assembly) {
     230          if ((PluginFileType)filetypeArg.TypedValue.Value == PluginFileType.Assembly) {
    227231            pluginAssemblies.Add(pluginDir + "/" + (string)filenameArg.TypedValue.Value);
    228232          }
     
    231235
    232236      // minimal sanity check of the attribute values
    233       if(pluginName != "" && pluginAssemblies.Count > 0) {
     237      if (pluginName != "" && pluginAssemblies.Count > 0) {
    234238        // create a temporary PluginInfo that contains the attribute values
    235239        PluginInfo info = new PluginInfo();
     
    247251
    248252    private void CheckPluginDependencies() {
    249       foreach(PluginInfo pluginInfo in preloadedPluginInfos) {
     253      foreach (PluginInfo pluginInfo in preloadedPluginInfos) {
    250254        // don't need to check plugins that are already disabled
    251         if(disabledPlugins.Contains(pluginInfo)) {
     255        if (disabledPlugins.Contains(pluginInfo)) {
    252256          continue;
    253257        }
    254258        visitedDependencies.Clear();
    255         if(!CheckPluginDependencies(pluginInfo.Name)) {
     259        if (!CheckPluginDependencies(pluginInfo.Name)) {
    256260          PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginInfo.Name; });
    257           if(matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen
    258           foreach(string dependency in pluginDependencies[matchingInfo]) {
     261          if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen
     262          foreach (string dependency in pluginDependencies[matchingInfo]) {
    259263            PluginInfo dependencyInfo = new PluginInfo();
    260264            dependencyInfo.Name = dependency;
     
    270274    private List<string> visitedDependencies = new List<string>();
    271275    private bool CheckPluginDependencies(string pluginName) {
    272       if(!preloadedPluginInfos.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) ||
     276      if (!preloadedPluginInfos.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) ||
    273277        disabledPlugins.Exists(delegate(PluginInfo info) { return pluginName == info.Name; }) ||
    274278        visitedDependencies.Contains(pluginName)) {
     
    280284
    281285        PluginInfo matchingInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == pluginName; });
    282         if(matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen
    283         foreach(string dependency in pluginDependencies[matchingInfo]) {
     286        if (matchingInfo == null) throw new InvalidProgramException(); // shouldn't happen
     287        foreach (string dependency in pluginDependencies[matchingInfo]) {
    284288          visitedDependencies.Add(pluginName);
    285           if(CheckPluginDependencies(dependency) == false) {
     289          if (CheckPluginDependencies(dependency) == false) {
    286290            // if only one dependency is not available that means that the current plugin also is unloadable
    287291            return false;
     
    298302    private void LoadPlugins() {
    299303      // load all loadable plugins (all dependencies available) into the execution context
    300       foreach(PluginInfo pluginInfo in preloadedPluginInfos) {
    301         if(!disabledPlugins.Contains(pluginInfo)) {
    302           foreach(string assembly in pluginInfo.Assemblies) {
     304      foreach (PluginInfo pluginInfo in preloadedPluginInfos) {
     305        if (!disabledPlugins.Contains(pluginInfo)) {
     306          foreach (string assembly in pluginInfo.Assemblies) {
    303307            Assembly.LoadFrom(assembly);
    304308          }
     
    308312      DiscoveryService service = new DiscoveryService();
    309313      // now search and instantiate an IPlugin type in each loaded assembly
    310       foreach(Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
     314      foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) {
    311315        // don't search for plugins in the PluginInfrastructure
    312         if(assembly == this.GetType().Assembly)
     316        if (assembly == this.GetType().Assembly)
    313317          continue;
    314318        Type[] availablePluginTypes = service.GetTypes(typeof(IPlugin), assembly);
    315         foreach(Type pluginType in availablePluginTypes) {
    316           if(!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
     319        foreach (Type pluginType in availablePluginTypes) {
     320          if (!pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
    317321            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
    318322            PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.InitializingPlugin));
     323            plugin.OnLoad();
    319324            pluginsByName.Add(plugin.Name, plugin);
    320325          }
     
    322327      }
    323328
    324       foreach(IPlugin plugin in pluginsByName.Values) {
     329      foreach (IPlugin plugin in pluginsByName.Values) {
    325330        PluginInfo pluginInfo = GetPluginInfo(plugin);
    326331        allPlugins.Add(pluginInfo, plugin);
     
    329334    }
    330335    private PluginInfo GetPluginInfo(IPlugin plugin) {
    331       if(pluginInfos.ContainsKey(plugin)) {
     336      if (pluginInfos.ContainsKey(plugin)) {
    332337        return pluginInfos[plugin];
    333338      }
     
    338343
    339344      object[] customAttributes = plugin.GetType().Assembly.GetCustomAttributes(typeof(AssemblyBuildDateAttribute), false);
    340       if(customAttributes.Length > 0) {
     345      if (customAttributes.Length > 0) {
    341346        pluginInfo.BuildDate = ((AssemblyBuildDateAttribute)customAttributes[0]).BuildDate;
    342347      }
     
    351356
    352357      PluginInfo preloadedInfo = preloadedPluginInfos.Find(delegate(PluginInfo info) { return info.Name == plugin.Name; });
    353       foreach(string assembly in preloadedInfo.Assemblies) {
     358      foreach (string assembly in preloadedInfo.Assemblies) {
    354359        // always use \ as directory separator (this is necessary for discovery of types in
    355360        // plugins see DiscoveryService.GetTypes()
    356361        pluginInfo.Assemblies.Add(assembly.Replace('/', '\\'));
    357362      }
    358       foreach(string dependency in pluginDependencies[preloadedInfo]) {
     363      foreach (string dependency in pluginDependencies[preloadedInfo]) {
    359364        // accumulate the dependencies of each assembly into the dependencies of the whole plugin
    360365        PluginInfo dependencyInfo = GetPluginInfo(pluginsByName[dependency]);
     
    366371
    367372    private void CheckPluginFiles() {
    368       foreach(PluginInfo plugin in preloadedPluginInfos) {
    369         if(!CheckPluginFiles(plugin)) {
     373      foreach (PluginInfo plugin in preloadedPluginInfos) {
     374        if (!CheckPluginFiles(plugin)) {
    370375          plugin.Message = "Disabled: missing plugin file.";
    371376          disabledPlugins.Add(plugin);
     
    375380
    376381    private bool CheckPluginFiles(PluginInfo pluginInfo) {
    377       foreach(string filename in pluginInfo.Files) {
    378         if(!File.Exists(filename)) {
    379           if(MissingPluginFile != null) {
     382      foreach (string filename in pluginInfo.Files) {
     383        if (!File.Exists(filename)) {
     384          if (MissingPluginFile != null) {
    380385            MissingPluginFile(pluginInfo.Name, filename);
    381386          }
     
    393398    internal void OnDelete(PluginInfo pluginInfo) {
    394399      IPlugin plugin = FindPlugin(pluginInfo);
    395       if(plugin!=null) plugin.OnDelete();
     400      if (plugin != null) plugin.OnDelete();
    396401    }
    397402
    398403    internal void OnInstall(PluginInfo pluginInfo) {
    399404      IPlugin plugin = FindPlugin(pluginInfo);
    400       if(plugin != null) plugin.OnInstall();
     405      if (plugin != null) plugin.OnInstall();
    401406    }
    402407
    403408    internal void OnPreUpdate(PluginInfo pluginInfo) {
    404409      IPlugin plugin = FindPlugin(pluginInfo);
    405       if(plugin != null) plugin.OnPreUpdate();
     410      if (plugin != null) plugin.OnPreUpdate();
    406411    }
    407412
    408413    internal void OnPostUpdate(PluginInfo pluginInfo) {
    409414      IPlugin plugin = FindPlugin(pluginInfo);
    410       if(plugin != null) plugin.OnPostUpdate();
     415      if (plugin != null) plugin.OnPostUpdate();
    411416    }
    412417  }
  • branches/CEDMA-Refactoring-Ticket419/HeuristicLab.PluginInfrastructure/Runner.cs

    r886 r1228  
    3939      }
    4040      //CodeAccessPermission.RevertAssert();
     41      FireOnLoad();
    4142      PluginManager.Manager.LoadedPlugins = plugins;
    4243    }
     
    4748    }
    4849
     50    private void FireOnLoad() {
     51      DiscoveryService service = new DiscoveryService();
     52      Array.ForEach(service.GetInstances<IPlugin>(), p => p.OnLoad());
     53    }
     54
    4955    // infinite lease time
    5056    public override object InitializeLifetimeService() {
Note: See TracChangeset for help on using the changeset viewer.