Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/12/09 17:45:45 (15 years ago)
Author:
gkronber
Message:

Worked on plugin infrastructure refactoring. (Fully functional revision). #799

Location:
branches/PluginInfrastructure Refactoring
Files:
4 added
14 edited
4 moved

Legend:

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

    r2481 r2488  
    2929  /// </summary>
    3030  [Serializable]
    31   public class ApplicationDescription {
     31  public class ApplicationDescription : IApplicationDescription {
    3232    private string name;
    3333
     
    6767    }
    6868
    69     private string pluginAssembly;
     69    private string declaringAssemblyName;
    7070    /// <summary>
    7171    /// Gets or sets the name of the assembly that contains the IApplication type.
    7272    /// </summary>
    73     public string PluginAssembly {
    74       get { return pluginAssembly; }
    75       set { pluginAssembly = value; }
     73    public string DeclaringAssemblyName {
     74      get { return declaringAssemblyName; }
     75      set { declaringAssemblyName = value; }
    7676    }
    7777
    78     private string pluginType;
     78    private string declaringTypeName;
    7979    /// <summary>
    8080    /// Gets or sets the name of the type that implements the interface IApplication.
    8181    /// </summary>
    82     public string PluginType {
    83       get { return pluginType; }
    84       set { pluginType = value; }
     82    public string DeclaringTypeName {
     83      get { return declaringTypeName; }
     84      set { declaringTypeName = value; }
    8585    }
    8686  }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/ApplicationManager.cs

    r2481 r2488  
    2727using System.Security.Permissions;
    2828using System.Security;
     29using System.Linq;
    2930
    3031namespace HeuristicLab.PluginInfrastructure.Manager {
    3132
    32   public class ApplicationManager {
     33  public class ApplicationManager : MarshalByRefObject, IApplicationManager {
     34    private List<IPluginDescription> plugins;
    3335    /// <summary>
    34     /// Event handler for actions in the application manager.
     36    /// Gets all plugins.
    3537    /// </summary>
    36     public event PluginManagerActionEventHandler Action;
    37 
    38     // singleton pattern
    39     public ApplicationManager() {
    40       applications = new List<ApplicationDescription>();
     38    public IEnumerable<IPluginDescription> Plugins {
     39      get { return plugins; }
    4140    }
    4241
    43     private ApplicationManager singleton = new ApplicationManager();
    44     public ApplicationManager Manager {
    45       get { return singleton; }
     42    private List<IApplicationDescription> applications;
     43    /// <summary>
     44    /// Gets all installed applications.
     45    /// </summary>
     46    public IEnumerable<IApplicationDescription> Applications {
     47      get { return applications; }
     48    }
     49
     50    public ApplicationManager() : base() { }
     51
     52    internal void PrepareApplicationDomain(IEnumerable<IApplicationDescription> apps, IEnumerable<IPluginDescription> plugins) {
     53      this.plugins = new List<IPluginDescription>(plugins);
     54      this.applications = new List<IApplicationDescription>(apps);
     55      PluginInfrastructure.ApplicationManager.RegisterApplicationManager(this);
     56      LoadPlugins(plugins);
     57    }
     58
     59    private void LoadPlugins(IEnumerable<IPluginDescription> plugins) {
     60      // load all loadable plugins (all dependencies available) into the execution context
     61      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
     62        foreach (var plugin in GetInstances<IPlugin>(desc)) {
     63          plugin.OnLoad();
     64        }
     65        desc.Load();
     66      }
     67    }
     68
     69    internal void Run(IApplicationDescription appInfo) {
     70      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
     71      try {
     72        runnablePlugin.Run();
     73      }
     74      catch (Exception e) {
     75        throw new Exception(String.Format(
     76          "Unexpected exception caught: \"{0}\"\r\n" +
     77          "Type: {1}\r\n" +
     78          "Plugin {2}:\r\n{3}",
     79          e.Message,
     80          e.GetType().FullName,
     81          appInfo.Name,
     82          e.ToString()));
     83      }
     84    }
     85
     86    /// <summary>
     87    /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
     88    /// </summary>
     89    /// <typeparam name="T">Most general type.</typeparam>
     90    /// <returns>Enumerable of the created instances.</returns>
     91    public IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class {
     92      return from t in GetTypes(typeof(T), plugin)
     93             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
     94             select (T)Activator.CreateInstance(t);
     95    }
     96    /// <summary>
     97    /// Creates an instance of all types that are subtypes or the same type of the specified type
     98    /// </summary>
     99    /// <typeparam name="T">Most general type.</typeparam>
     100    /// <returns>Enumerable of the created instances.</returns>
     101    public IEnumerable<T> GetInstances<T>() where T : class {
     102      return from i in GetInstances(typeof(T))
     103             select (T)i;
     104    }
     105
     106    /// <summary>
     107    /// Creates an instance of all types that are subtypes or the same type of the specified type
     108    /// </summary>
     109    /// <typeparam name="type">Most general type.</typeparam>
     110    /// <returns>Enumerable of the created instances.</returns>
     111    public IEnumerable<object> GetInstances(Type type) {
     112      return from t in GetTypes(type)
     113             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
     114             select Activator.CreateInstance(t);
     115    }
     116
     117    /// <summary>
     118    /// Finds all types that are subtypes or equal to the specified type.
     119    /// </summary>
     120    /// <param name="type">Most general type for which to find matching types.</param>
     121    /// <returns>Enumerable of the discovered types.</returns>
     122    public IEnumerable<Type> GetTypes(Type type) {
     123      return from asm in AppDomain.CurrentDomain.GetAssemblies()
     124             from t in GetTypes(type, asm)
     125             select t;
     126    }
     127
     128    /// <summary>
     129    /// Finds all types that are subtypes or equal to the specified type if they are part of the given
     130    /// <paramref name="plugin"/>.
     131    /// </summary>
     132    /// <param name="type">Most general type for which to find matching types.</param>
     133    /// <param name="plugin">The plugin the subtypes must be part of.</param>
     134    /// <returns>Enumerable of the discovered types.</returns>
     135    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;
     140    }
     141
     142    /// <summary>
     143    /// Gets types that are assignable (same of subtype) to the specified type only from the given assembly.
     144    /// </summary>
     145    /// <param name="type">Most general type we want to find.</param>
     146    /// <param name="assembly">Assembly that should be searched for types.</param>
     147    /// <returns>Enumerable of the discovered types.</returns>
     148    private IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
     149      return from t in assembly.GetTypes()
     150             where type.IsAssignableFrom(t)
     151             select t;
    46152    }
    47153
    48154
    49     private void NotifyListeners(string action, string text) {
    50       if (Action != null) {
    51         Action(this, new PluginManagerActionEventArgs(text, action));
    52       }
     155    // infinite lease time
     156    /// <summary>
     157    /// Initializes the life time service with infinite lease time.
     158    /// </summary>
     159    /// <returns><c>null</c>.</returns>
     160    public override object InitializeLifetimeService() {
     161      return null;
    53162    }
    54163  }
    55164}
     165
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/HeuristicLab.PluginInfrastructure.Manager.csproj

    r2481 r2488  
    4949  <ItemGroup>
    5050    <Compile Include="ApplicationDescription.cs" />
    51     <Compile Include="PluginDescriptionIterator.cs" />
     51    <Compile Include="ApplicationManager.cs">
     52      <SubType>Code</SubType>
     53    </Compile>
    5254    <Compile Include="Loader.cs" />
    53     <Compile Include="PluginState.cs" />
    5455    <Compile Include="PluginDescription.cs" />
    5556    <Compile Include="PluginManager.cs" />
    5657    <Compile Include="PluginManagerActionEventArgs.cs" />
    5758    <Compile Include="Properties\AssemblyInfo.cs" />
    58     <Compile Include="Runner.cs" />
    5959  </ItemGroup>
    6060  <ItemGroup>
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Loader.cs

    r2481 r2488  
    5555      this.plugins = new List<PluginDescription>();
    5656      this.pluginDependencies = new Dictionary<PluginDescription, List<string>>();
     57
     58      AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ReflectionOnlyAssemblyResolveEventHandler;
     59    }
     60
     61    private Assembly ReflectionOnlyAssemblyResolveEventHandler(object sender, ResolveEventArgs args) {
     62      //try {
     63      return Assembly.ReflectionOnlyLoad(args.Name);
     64      //}
     65      //catch (FileLoadException ex) {
     66      //  return null;
     67      //}
    5768    }
    5869
     
    7081    /// </summary>
    7182    internal void Init() {
    72       //AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += delegate(object sender, ResolveEventArgs args) {
    73       //  try {
    74       //    return Assembly.ReflectionOnlyLoad(args.Name);
    75       //  }
    76       //  catch (FileLoadException ex) {
    77       //    return null;
    78       //  }
    79       //};
    8083      pluginDependencies.Clear();
    8184
     
    9194      CheckPluginDependencies(pluginDescriptions);
    9295
     96      // mark all plugins as enabled that were not disabled in CheckPluginFiles or CheckPluginDependencies
     97      foreach (var desc in pluginDescriptions)
     98        if (desc.PluginState != PluginState.Disabled)
     99          desc.Enable();
     100
    93101      // test full loading (in contrast to reflection only loading) of plugins
    94102      // disables plugins that are not loaded correctly
     
    100108
    101109    private void DiscoverApplications() {
    102       DiscoveryService service = new DiscoveryService();
    103       IApplication[] apps = service.GetInstances<IApplication>();
    104110      applications = new List<ApplicationDescription>();
    105111
    106       foreach (IApplication application in apps) {
     112      foreach (IApplication application in GetApplications()) {
    107113        ApplicationDescription info = new ApplicationDescription();
    108114        info.Name = application.Name;
     
    110116        info.Description = application.Description;
    111117        info.AutoRestart = application.RestartOnErrors;
    112         info.PluginAssembly = application.GetType().Assembly.GetName().Name;
    113         info.PluginType = application.GetType().Namespace + "." + application.GetType().Name;
     118        info.DeclaringAssemblyName = application.GetType().Assembly.GetName().Name;
     119        info.DeclaringTypeName = application.GetType().Namespace + "." + application.GetType().Name;
    114120
    115121        applications.Add(info);
    116122      }
     123    }
     124
     125    private IEnumerable<IApplication> GetApplications() {
     126      return from asm in AppDomain.CurrentDomain.GetAssemblies()
     127             from t in asm.GetTypes()
     128             where typeof(IApplication).IsAssignableFrom(t) &&
     129               !t.IsAbstract && !t.IsInterface && !t.HasElementType
     130             select (IApplication)Activator.CreateInstance(t);
    117131    }
    118132
     
    198212      // iterate through all custom attributes and search for attributed that we are interested in
    199213      foreach (CustomAttributeData attributeData in attributes) {
    200         if (IsAttributeDataForType(attributeData, typeof(PluginDescriptionAttribute))) {
     214        if (IsAttributeDataForType(attributeData, typeof(PluginAttribute))) {
    201215          pluginName = (string)attributeData.ConstructorArguments[0].Value;
    202216        } else if (IsAttributeDataForType(attributeData, typeof(PluginDependencyAttribute))) {
     
    222236        info.AddAssemblies(pluginAssemblies);
    223237        info.AddFiles(pluginFiles);
    224         info.PluginState = PluginState.Undefined;
    225238
    226239        this.pluginDependencies[info] = pluginDependencies;
     
    246259          } else {
    247260            // no plugin description that matches the dependency name is available => plugin is disabled
    248             desc.PluginState = PluginState.Disabled;
     261            desc.Disable();
    249262            break; // stop processing more dependencies
    250263          }
     
    257270        if (IsAnyDependencyDisabled(pluginDescription)) {
    258271          // PluginDescription.Message = "Disabled: missing plugin dependency.";
    259           pluginDescription.PluginState = PluginState.Disabled;
     272          pluginDescription.Disable();
    260273        }
    261274      }
     
    273286    private void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) {
    274287      // load all loadable plugins (all dependencies available) into the execution context
    275       foreach (PluginDescription desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) {
     288      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions
     289                                                                                .Cast<IPluginDescription>()
     290                                                                                .Where(x => x.PluginState != PluginState.Disabled))) {
    276291        List<Type> types = new List<Type>();
    277292        foreach (string assembly in desc.Assemblies) {
     
    288303            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
    289304            plugin.OnLoad();
     305            desc.Load();
    290306            PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded));
    291307          }
     
    335351        if (!CheckPluginFiles(desc)) {
    336352          //plugin.Message = "Disabled: missing plugin file.";
    337           desc.PluginState = PluginState.Disabled;
     353          desc.Disable();
    338354        }
    339355      }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginDescription.cs

    r2481 r2488  
    3030  /// </summary>
    3131  [Serializable]
    32   public class PluginDescription {
     32  public class PluginDescription : IPluginDescription {
    3333    private string name;
    3434    /// <summary>
     
    6262    public PluginState PluginState {
    6363      get { return pluginState; }
    64       set { pluginState = value; }
     64    }
     65
     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;
    6591    }
    6692
     
    78104    }
    79105
    80     private List<PluginDescription> dependencies = new List<PluginDescription>();
     106    private List<IPluginDescription> dependencies = new List<IPluginDescription>();
    81107    /// <summary>
    82108    /// Gets all dependencies of the plugin.
    83109    /// </summary>
    84     public IEnumerable<PluginDescription> Dependencies {
     110    public IEnumerable<IPluginDescription> Dependencies {
    85111      get { return dependencies; }
    86112    }
     
    104130    }
    105131
     132    public PluginDescription() {
     133      nTimesLoaded = 0;
     134      pluginState = PluginState.Undefined;
     135    }
     136
     137
    106138    //private string message;
    107139    ///// <summary>
     
    121153    }
    122154
    123     // equals and hashcode have to be implemented because we want to compare PluginDescriptions from
    124     // different AppDomains and serialization destroys reference equality
    125     /// <summary>
    126     /// Checks whether the given object is equal to the current plugin.
    127     /// </summary>
    128     /// <param name="obj">The object to compare.</param>
    129     /// <returns><c>true</c> if it is equal, <c>false</c> otherwise.</returns>
    130     public override bool Equals(object obj) {
    131       if (!(obj is PluginDescription))
    132         return false;
    133       PluginDescription other = (PluginDescription)obj;
     155    //// equals and hashcode have to be implemented because we want to compare PluginDescriptions from
     156    //// different AppDomains and serialization destroys reference equality
     157    ///// <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;
    134166
    135       return other.Name == this.Name && other.Version == this.Version;
    136     }
    137     /// <summary>
    138     /// Gets the hash code of the current plugin.
    139     /// </summary>
    140     /// <returns>The hash code of the plugin.</returns>
    141     public override int GetHashCode() {
    142       if (version != null) {
    143         return name.GetHashCode() + version.GetHashCode();
    144       } else return name.GetHashCode();
    145     }
     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    //}
    146178  }
    147179}
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/PluginManager.cs

    r2481 r2488  
    2727using System.Security.Permissions;
    2828using System.Security;
     29using System.Linq;
    2930
    3031namespace HeuristicLab.PluginInfrastructure.Manager {
     
    8182
    8283    private List<PluginDescription> plugins;
    83     public IEnumerable<PluginDescription> Plugins {
    84       get { return plugins; }
    85     }
     84    //public IEnumerable<PluginDescription> Plugins {
     85    //  get { return plugins; }
     86    //}
    8687
    8788    private List<ApplicationDescription> applications;
     
    109110      plugins = new List<PluginDescription>(remoteLoader.Plugins);
    110111      applications = new List<ApplicationDescription>(remoteLoader.Applications);
    111       throw new NotImplementedException();
     112
     113      // discard the AppDomain that was used for plugin discovery
     114      UnloadAppDomain(pluginDomain);
     115    }
     116
     117    private void UnloadAppDomain(AppDomain appDomain) {
     118      AppDomain.Unload(appDomain);
     119
     120      // set all loaded plugins back to enabled
     121      foreach (var pluginDescription in plugins)
     122        pluginDescription.Unload();
    112123    }
    113124
     
    130141    public void Run(ApplicationDescription appInfo) {
    131142      // create a separate AppDomain for the application
    132       // activate a PluginRunner instance in the application
     143      // initialize the static ApplicationManager in the AppDomain
    133144      // and remotely tell it to start the application
    134145
     
    139150        setup.PrivateBinPath = pluginDir;
    140151        applicationDomain = AppDomain.CreateDomain(appInfo.Name, null, setup);
    141         Runner remoteRunner = (Runner)applicationDomain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.GetName().Name, typeof(Runner).FullName);
    142         remoteRunner.PluginAction += delegate(object sender, PluginManagerActionEventArgs args) { if (Action != null) Action(this, args); };
    143         remoteRunner.LoadPlugins(Plugins);
     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); };
     155        applicationManager.PrepareApplicationDomain(
     156          new List<IApplicationDescription>(applications.Cast<IApplicationDescription>()),
     157          new List<IPluginDescription>(plugins.Cast<IPluginDescription>()));
    144158        NotifyListeners(PluginManagerAction.Initialized, "All plugins");
    145         remoteRunner.Run(appInfo);
     159        applicationManager.Run(appInfo);
    146160      }
    147161      finally {
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure.Manager/Runner.cs

    r2481 r2488  
    4444    }
    4545
    46     public void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) {
     46    public void LoadPlugins(IEnumerable<IPluginDescription> pluginDescriptions) {
    4747      //FileIOPermission fileperm = new FileIOPermission(FileIOPermissionAccess.AllAccess, @"C:\Program Files\HeuristicLab 3.0\plugins\");
    4848      //fileperm.Assert();
    4949
    5050      // load all loadable plugins (all dependencies available) into the execution context
    51       foreach (PluginDescription desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) {
     51      foreach (var desc in PluginDescriptionIterator.IterateInDependencyOrder(pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled))) {
    5252        List<Type> types = new List<Type>();
    5353        foreach (string assembly in desc.Assemblies) {
     
    6464            IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
    6565            plugin.OnLoad();
     66            desc.Load();
    6667            PluginAction(this, new PluginManagerActionEventArgs(plugin.Name, PluginManagerAction.PluginLoaded));
    6768          }
     
    8889
    8990    public void Run(ApplicationDescription appInfo) {
    90       IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.PluginAssembly, appInfo.PluginType).Unwrap();
     91      IApplication runnablePlugin = (IApplication)Activator.CreateInstance(appInfo.DeclaringAssemblyName, appInfo.DeclaringTypeName).Unwrap();
    9192      try {
    9293        runnablePlugin.Run();
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Attributes/ApplicationAttribute.cs

    r2475 r2488  
    3030  /// </summary>
    3131  [AttributeUsage(AttributeTargets.Class)]
    32   public class ApplicationDescriptionAttribute : System.Attribute {
     32  public class ApplicationAttribute : System.Attribute {
    3333    private string name;
    3434    /// <summary>
     
    4040    }
    4141
    42     private string version;
    43     /// <summary>
    44     /// Gets or sets the version of the application.
    45     /// </summary>
    46     public string Version {
    47       get { return version; }
    48       set { version = value; }
    49     }
     42    //private string version;
     43    ///// <summary>
     44    ///// Gets or sets the version of the application.
     45    ///// </summary>
     46    //public string Version {
     47    //  get { return version; }
     48    //  set { version = value; }
     49    //}
    5050
    5151    private string description;
     
    6868
    6969    /// <summary>
    70     /// Initializes a new instance of <see cref="ApplicationDescriptionAttribute"/>.
     70    /// Initializes a new instance of <see cref="ApplicationAttribute"/>.
    7171    /// <param name="name">Name of the application</param>
    7272    /// </summary>
    73     public ApplicationDescriptionAttribute(string name)
     73    public ApplicationAttribute(string name)
    7474      : this(name, "") {
    7575    }
    7676
    7777    /// <summary>
    78     /// Initializes a new instance of <see cref="ApplicationDescriptionAttribute"/>.
     78    /// Initializes a new instance of <see cref="ApplicationAttribute"/>.
    7979    /// <param name="name">Name of the application</param>
    8080    /// <param name="description">Description of the application</param>
    8181    /// </summary>
    82     public ApplicationDescriptionAttribute(string name, string description)
    83       : this(name, description, "") {
     82    public ApplicationAttribute(string name, string description)
     83      : this(name, description, false) {
    8484    }
    8585
    86     /// <summary>
    87     /// Initializes a new instance of <see cref="ApplicationDescriptionAttribute"/>.
    88     /// <param name="name">Name of the application</param>
    89     /// <param name="description">Description of the application</param>
    90     /// <param name="version">Version string of the application</param>
    91     /// </summary>
    92     public ApplicationDescriptionAttribute(string name, string description, string version)
    93       : this(name, description, version, false) {
    94     }
     86    ///// <summary>
     87    ///// Initializes a new instance of <see cref="ApplicationAttribute"/>.
     88    ///// <param name="name">Name of the application</param>
     89    ///// <param name="description">Description of the application</param>
     90    ///// <param name="version">Version string of the application</param>
     91    ///// </summary>
     92    //public ApplicationAttribute(string name, string description, string version)
     93    //  : this(name, description, version, false) {
     94    //}
    9595
    9696    /// <summary>
    97     /// Initializes a new instance of <see cref="ApplicationDescriptionAttribute"/>.
     97    /// Initializes a new instance of <see cref="ApplicationAttribute"/>.
    9898    /// <param name="name">Name of the application</param>
    9999    /// <param name="description">Description of the application</param>
     
    101101    /// <param name="restartOnErrors">Flag that indicates if the application should be restarted on exceptions (for services)</param>
    102102    /// </summary>
    103     public ApplicationDescriptionAttribute(string name, string description, string version, bool restartOnErrors) {
     103    public ApplicationAttribute(string name, string description, bool restartOnErrors) {
    104104      this.name = name;
    105       this.version = version;
    106105      this.description = description;
    107106      this.restartOnErrors = restartOnErrors;
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Attributes/PluginAttribute.cs

    r2481 r2488  
    3030  /// </summary>
    3131  [AttributeUsage(AttributeTargets.Class)]
    32   public class PluginDescriptionAttribute : System.Attribute {
     32  public class PluginAttribute : System.Attribute {
    3333    private string name;
    3434    /// <summary>
     
    4949    //}
    5050
    51     //private string description;
    52     ///// <summary>
    53     ///// Gets or sets the description of the plugin.
    54     ///// </summary>
    55     //public string Description {
    56     //  get { return description; }
    57     // set { description = value; }
    58     //}
     51    private string description;
     52    /// <summary>
     53    /// Gets or sets the description of the plugin.
     54    /// </summary>
     55    public string Description {
     56      get { return description; }
     57      // set { description = value; }
     58    }
    5959
    6060    /// <summary>
    61     /// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>.
     61    /// Initializes a new instance of <see cref="PluginAttribute"/>.
    6262    /// <param name="name">Name of the plugin</param>
    6363    /// </summary>
    64     public PluginDescriptionAttribute(string name) {
    65       this.name = name;
     64    public PluginAttribute(string name)
     65      : this(name, "") {
    6666    }
    6767
    68     ///// <summary>
    69     ///// Initializes a new instance of <see cref="PluginDescriptionAttribute"/>.
    70     ///// <param name="name">Name of the plugin</param>
    71     ///// <param name="description">Description of the plugin</param>
    72     ///// </summary>
    73     //public PluginDescriptionAttribute(string name, string description)
    74     //  : this(name, description, "") {
    75     //}
     68    /// <summary>
     69    /// Initializes a new instance of <see cref="PluginAttribute"/>.
     70    /// <param name="name">Name of the plugin</param>
     71    /// <param name="description">Description of the plugin</param>
     72    /// </summary>
     73    public PluginAttribute(string name, string description) {
     74      this.name = name;
     75      this.description = description;
     76    }
    7677
    7778    ///// <summary>
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/ApplicationBase.cs

    r2475 r2488  
    2929  /// Default implementation for the IApplication interface.
    3030  /// </summary>
    31   internal abstract class ApplicationBase : IApplication {
     31  public abstract class ApplicationBase : IApplication {
    3232    /// <summary>
    3333    /// Initializes a new instance of <see cref="ApplicationBase"/>.
     
    3535    public ApplicationBase() { }
    3636
    37     private ApplicationDescriptionAttribute ApplicationDescriptionAttribute {
     37    private ApplicationAttribute ApplicationAttribute {
    3838      get {
    39         object[] appDescAttributes = this.GetType().GetCustomAttributes(typeof(ApplicationDescriptionAttribute), false);
     39        object[] appAttributes = this.GetType().GetCustomAttributes(typeof(ApplicationAttribute), false);
    4040
    4141        // exactly one attribute of the type ClassInfoAttribute must be given
    42         if (appDescAttributes.Length != 1) {
    43           throw new InvalidPluginException("Found multiple ApplicationDescriptionAttributes on type " + this.GetType());
     42        if (appAttributes.Length != 1) {
     43          throw new InvalidPluginException("Found multiple ApplicationAttributes on type " + this.GetType());
    4444        }
    4545
    46         return (ApplicationDescriptionAttribute)appDescAttributes[0];
     46        return (ApplicationAttribute)appAttributes[0];
    4747      }
    4848    }
     
    5454    /// </summary>
    5555    public string Name {
    56       get { return ApplicationDescriptionAttribute.Name; }
     56      get { return ApplicationAttribute.Name; }
    5757    }
    5858
     
    6262    public Version Version {
    6363      get {
    64         var appDescAttribute = ApplicationDescriptionAttribute;
    65         // if the version is not explicitly set in the attribute then the version of the assembly is used as default
    66         if (string.IsNullOrEmpty(appDescAttribute.Version)) {
    67           return this.GetType().Assembly.GetName().Version;
    68         } else {
    69           return new Version(appDescAttribute.Version);
    70         }
     64        return this.GetType().Assembly.GetName().Version;
    7165      }
    7266    }
     
    7771    public string Description {
    7872      get {
    79         var appDescAttribute = ApplicationDescriptionAttribute;
     73        var appDescAttribute = ApplicationAttribute;
    8074        // if the description is not explicitly set in the attribute then the name of the application is used as default
    8175        if (string.IsNullOrEmpty(appDescAttribute.Description)) {
     
    9286    public bool RestartOnErrors {
    9387      get {
    94         return ApplicationDescriptionAttribute.RestartOnErrors;
     88        return ApplicationAttribute.RestartOnErrors;
    9589      }
    9690    }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/BaseClasses/PluginBase.cs

    r2481 r2488  
    3737    public PluginBase() { }
    3838
    39     private PluginDescriptionAttribute PluginDescriptionAttribute {
     39    private PluginAttribute PluginAttribute {
    4040      get {
    41         object[] pluginAttributes = this.GetType().GetCustomAttributes(typeof(PluginDescriptionAttribute), false);
     41        object[] pluginAttributes = this.GetType().GetCustomAttributes(typeof(PluginAttribute), false);
    4242        // exactly one attribute of the type PluginDescriptionAttribute must be given
    4343        if (pluginAttributes.Length != 1) {
    44           throw new InvalidPluginException("Found multiple PluginDescriptionAttributes on type " + this.GetType());
     44          throw new InvalidPluginException("Found multiple PluginAttributes on type " + this.GetType());
    4545        }
    46         return (PluginDescriptionAttribute)pluginAttributes[0];
     46        return (PluginAttribute)pluginAttributes[0];
    4747      }
    4848    }
     
    5252    public string Name {
    5353      get {
    54         return PluginDescriptionAttribute.Name;
     54        return PluginAttribute.Name;
    5555      }
    5656    }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/ControlManager.cs

    r2481 r2488  
    3838    public static IControlManager Manager {
    3939      get { return controlManager; }
    40       set { controlManager = value; }
     40    }
     41
     42    public static void RegisterManager(IControlManager manager) {
     43      if (controlManager != null) throw new InvalidOperationException("An control manager has already been set.");
     44      controlManager = manager;
    4145    }
    4246  }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/DiscoveryService.cs

    r2481 r2488  
    2424using System.Text;
    2525using System.Reflection;
     26using System.Linq;
    2627
    2728namespace HeuristicLab.PluginInfrastructure {
     
    3031  /// </summary>
    3132  public class DiscoveryService {
     33    //internal static IEnumerable<IPluginDescription> plugins;
    3234
    33     //public PluginDescription[] Plugins {
     35    //public IEnumerable<IPluginDescription> Plugins {
    3436    //  get {
    35     //    PluginInfo[] plugins = new PluginInfo[PluginManager.Manager.LoadedPlugins.Count];
    36     //    PluginManager.Manager.LoadedPlugins.CopyTo(plugins, 0);
    37     //    return plugins;
     37    //    return DiscoveryService.plugins;
    3838    //  }
    3939    //}
    4040
    4141    /// <summary>
    42     /// Finds all types that are subtypes or equal to the specified type.
     42    /// Creates an instance of all types that are subtypes or the same type of the specified type and declared in <paramref name="plugin"/>
    4343    /// </summary>
    44     /// <param name="type">Most general type for which to find matching types.</param>
    45     /// <returns>The found types as array.</returns>
    46     public Type[] GetTypes(Type type) {
    47       Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    48       List<Type> types = new List<Type>();
    49       foreach (Assembly asm in assemblies) {
    50         Array.ForEach<Type>(GetTypes(type, asm), delegate(Type t) {
    51           types.Add(t);
    52         });
    53       }
    54       return types.ToArray();
     44    /// <typeparam name="T">Most general type.</typeparam>
     45    /// <returns>Enumerable of the created instances.</returns>
     46    public IEnumerable<T> GetInstances<T>(IPluginDescription plugin) where T : class {
     47      return from t in GetTypes(typeof(T), plugin)
     48             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
     49             select (T)Activator.CreateInstance(t);
    5550    }
    56 
    5751    /// <summary>
    5852    /// Creates an instance of all types that are subtypes or the same type of the specified type
    5953    /// </summary>
    6054    /// <typeparam name="T">Most general type.</typeparam>
    61     /// <returns>The created instances as array.</returns>
    62     public T[] GetInstances<T>() where T : class {
    63       Type[] types = GetTypes(typeof(T));
    64       List<T> instances = new List<T>();
    65       foreach (Type t in types) {
    66         if (!t.IsAbstract && !t.IsInterface && !t.HasElementType) {
    67           instances.Add((T)Activator.CreateInstance(t));
    68         }
    69       }
    70       return instances.ToArray();
     55    /// <returns>Enumerable of the created instances.</returns>
     56    public IEnumerable<T> GetInstances<T>() where T : class {
     57      return from i in GetInstances(typeof(T))
     58             select (T)i;
    7159    }
    7260
     
    7563    /// </summary>
    7664    /// <typeparam name="type">Most general type.</typeparam>
    77     /// <returns>The created instances as array.</returns>
    78     public object[] GetInstances(Type type) {
    79       Type[] types = GetTypes(type);
    80       List<object> instances = new List<object>();
    81       foreach (Type t in types) {
    82         if (!t.IsAbstract && !t.IsInterface && !t.HasElementType) {
    83           instances.Add(Activator.CreateInstance(t));
    84         }
    85       }
    86       return instances.ToArray();
     65    /// <returns>Enumerable of the created instances.</returns>
     66    public IEnumerable<object> GetInstances(Type type) {
     67      return from t in GetTypes(type)
     68             where !t.IsAbstract && !t.IsInterface && !t.HasElementType
     69             select Activator.CreateInstance(t);
    8770    }
    8871
    89     ///// <summary>
    90     ///// Finds all types that are subtypes or equal to the specified type if they are part of the given
    91     ///// <paramref name="plugin"/>.
    92     ///// </summary>
    93     ///// <param name="type">Most general type for which to find matching types.</param>
    94     ///// <param name="plugin">The plugin the subtypes must be part of.</param>
    95     ///// <returns>The found types as array.</returns>
    96     //public Type[] GetTypes(Type type, PluginInfo plugin) {
    97     //  Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    98     //  List<Type> types = new List<Type>();
    99     //  foreach (Assembly asm in assemblies) {
    100     //    if (plugin.Assemblies.Contains(asm.Location)) {
    101     //      Array.ForEach<Type>(GetTypes(type, asm), delegate(Type t) {
    102     //        types.Add(t);
    103     //      });
    104     //    }
    105     //  }
     72    /// <summary>
     73    /// Finds all types that are subtypes or equal to the specified type.
     74    /// </summary>
     75    /// <param name="type">Most general type for which to find matching types.</param>
     76    /// <returns>Enumerable of the discovered types.</returns>
     77    public IEnumerable<Type> GetTypes(Type type) {
     78      return from asm in AppDomain.CurrentDomain.GetAssemblies()
     79             from t in GetTypes(type, asm)
     80             select t;
     81    }
    10682
    107     //  return types.ToArray();
    108     //}
     83    /// <summary>
     84    /// Finds all types that are subtypes or equal to the specified type if they are part of the given
     85    /// <paramref name="plugin"/>.
     86    /// </summary>
     87    /// <param name="type">Most general type for which to find matching types.</param>
     88    /// <param name="plugin">The plugin the subtypes must be part of.</param>
     89    /// <returns>Enumerable of the discovered types.</returns>
     90    public IEnumerable<Type> GetTypes(Type type, IPluginDescription pluginDescription) {
     91      return from asm in AppDomain.CurrentDomain.GetAssemblies()
     92             where pluginDescription.Assemblies.Contains(asm.Location)
     93             from t in GetTypes(type, asm)
     94             select t;
     95    }
    10996
    11097    ///// <summary>
     
    130117    /// <param name="type">Most general type we want to find.</param>
    131118    /// <param name="assembly">Assembly that should be searched for types.</param>
    132     /// <returns>The found types as array.</returns>
    133     internal Type[] GetTypes(Type type, Assembly assembly) {
    134       List<Type> types = new List<Type>();
    135       foreach (Type t in assembly.GetTypes()) {
    136         if (type.IsAssignableFrom(t)) {
    137           types.Add(t);
    138         }
    139       }
    140       return types.ToArray();
     119    /// <returns>Enumerable of the discovered types.</returns>
     120    private IEnumerable<Type> GetTypes(Type type, Assembly assembly) {
     121      return from t in assembly.GetTypes()
     122             where type.IsAssignableFrom(t)
     123             select t;
    141124    }
    142125
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/HeuristicLab.PluginInfrastructure.csproj

    r2481 r2488  
    8686  </ItemGroup>
    8787  <ItemGroup>
    88     <Compile Include="Attributes\ApplicationDescriptionAttribute.cs" />
     88    <Compile Include="Attributes\ApplicationAttribute.cs" />
    8989    <Compile Include="Attributes\AssemblyBuildDateAttribute.cs" />
     90    <Compile Include="Attributes\PluginAttribute.cs" />
    9091    <Compile Include="Attributes\PluginDependencyAttribute.cs" />
    91     <Compile Include="Attributes\PluginDescriptionAttribute.cs" />
    9292    <Compile Include="Attributes\PluginFileAttribute.cs" />
    9393    <Compile Include="BaseClasses\ApplicationBase.cs" />
    9494    <Compile Include="BaseClasses\PluginBase.cs" />
     95    <Compile Include="Interfaces\IApplicationManager.cs" />
     96    <Compile Include="Interfaces\IApplicationDescription.cs" />
    9597    <Compile Include="Interfaces\IApplication.cs" />
    9698    <Compile Include="Interfaces\IControl.cs" />
    9799    <Compile Include="Interfaces\IControlManager.cs" />
    98100    <Compile Include="Interfaces\IPlugin.cs" />
    99     <Compile Include="DiscoveryService.cs" />
    100101    <Compile Include="ControlManager.cs" />
     102    <Compile Include="Interfaces\IPluginDescription.cs" />
    101103    <Compile Include="InvalidPluginException.cs" />
     104    <Compile Include="PluginDescriptionIterator.cs" />
     105    <Compile Include="ApplicationManager.cs" />
     106    <Compile Include="PluginState.cs" />
    102107    <Compile Include="Properties\AssemblyInfo.cs" />
    103108    <EmbeddedResource Include="Properties\Resources.resx">
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginDescriptionIterator.cs

    r2481 r2488  
    2424using System.Text;
    2525
    26 namespace HeuristicLab.PluginInfrastructure.Manager {
     26namespace HeuristicLab.PluginInfrastructure {
    2727  public static class PluginDescriptionIterator {
    28     public static IEnumerable<PluginDescription> IterateInDependencyOrder(IEnumerable<PluginDescription> pluginDescriptions) {
     28    public static IEnumerable<IPluginDescription> IterateInDependencyOrder(IEnumerable<IPluginDescription> pluginDescriptions) {
    2929      // list to make sure we yield each description only once
    30       List<PluginDescription> yieldedDescriptions = new List<PluginDescription>();
     30      List<IPluginDescription> yieldedDescriptions = new List<IPluginDescription>();
    3131      foreach (var desc in pluginDescriptions) {
    3232        foreach (var dependency in IterateInDependencyOrder(desc.Dependencies)) {
     
    3535            yield return dependency;
    3636          }
    37           if (!yieldedDescriptions.Contains(desc)) {
    38             yieldedDescriptions.Add(desc);
    39             yield return desc;
    40           }
     37        }
     38        if (!yieldedDescriptions.Contains(desc)) {
     39          yieldedDescriptions.Add(desc);
     40          yield return desc;
    4141        }
    4242      }
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/PluginState.cs

    r2481 r2488  
    2424using System.Text;
    2525
    26 namespace HeuristicLab.PluginInfrastructure.Manager {
     26namespace HeuristicLab.PluginInfrastructure {
    2727  [Serializable]
    2828  public enum PluginState {
  • branches/PluginInfrastructure Refactoring/HeuristicLab/MainForm.cs

    r2481 r2488  
    3737    private ListViewItem pluginManagerListViewItem;
    3838    private bool abortRequested;
     39    private PluginManager pluginManager;
    3940
    4041    public MainForm()
     
    4344
    4445      abortRequested = false;
    45       PluginManager pluginManager = new PluginManager(HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir);
     46      pluginManager = new PluginManager(HeuristicLab.PluginInfrastructure.Properties.Settings.Default.PluginDir);
    4647      SplashScreen splashScreen = new SplashScreen(pluginManager, 1000, "Loading HeuristicLab...");
    4748      splashScreen.Owner = this;
     
    8384        if (selected == pluginManagerListViewItem) {
    8485          try {
    85             Cursor = Cursors.AppStarting;
    86             ManagerForm form = new ManagerForm();
    87             this.Visible = false;
    88             form.ShowDialog(this);
    89             // RefreshApplicationsList();
    90             this.Visible = true;
     86            //Cursor = Cursors.AppStarting;
     87            //ManagerForm form = new ManagerForm();
     88            //this.Visible = false;
     89            //form.ShowDialog(this);
     90            //// RefreshApplicationsList();
     91            //this.Visible = true;
    9192          }
    9293          finally {
     
    9596        } else {
    9697          ApplicationDescription app = (ApplicationDescription)applicationsListView.SelectedItems[0].Tag;
    97           SplashScreen splashScreen = new SplashScreen(2000, "Loading " + app.Name);
     98          SplashScreen splashScreen = new SplashScreen(pluginManager, 2000, "Loading " + app.Name);
    9899          splashScreen.Owner = this;
    99100          splashScreen.Show();
    100           PluginManager.Manager.Action += new PluginManagerActionEventHandler(splashScreen.Manager_Action);
    101101          Thread t = new Thread(delegate() {
    102102            bool stopped = false;
     
    104104              try {
    105105                if (!abortRequested)
    106                   PluginManager.Manager.Run(app);
     106                  pluginManager.Run(app);
    107107                stopped = true;
    108108              }
  • branches/PluginInfrastructure Refactoring/HeuristicLab/Program.cs

    r1107 r2488  
    3838          Application.Run(new MainForm());
    3939        } else if (args.Length == 1) {  // start specific application
    40           PluginManager.Manager.Initialize();
     40          //PluginManager.Manager.Initialize();
    4141
    42           ApplicationInfo app = null;
    43           foreach (ApplicationInfo info in PluginManager.Manager.InstalledApplications) {
    44             if (info.Name == args[0])
    45               app = info;
    46           }
    47           if (app == null) {  // application not found
    48             MessageBox.Show("Cannot start application.\nApplication " + args[0] + " is not installed.\n\nStarting HeuristicLab in normal mode ...",
    49                             "HeuristicLab",
    50                             MessageBoxButtons.OK,
    51                             MessageBoxIcon.Warning);
    52             Application.EnableVisualStyles();
    53             Application.SetCompatibleTextRenderingDefault(false);
    54             Application.Run(new MainForm());
    55           } else {
    56             PluginManager.Manager.Run(app);
    57           }
     42          //ApplicationInfo app = null;
     43          //foreach (ApplicationInfo info in PluginManager.Manager.InstalledApplications) {
     44          //  if (info.Name == args[0])
     45          //    app = info;
     46          //}
     47          //if (app == null) {  // application not found
     48          //  MessageBox.Show("Cannot start application.\nApplication " + args[0] + " is not installed.\n\nStarting HeuristicLab in normal mode ...",
     49          //                  "HeuristicLab",
     50          //                  MessageBoxButtons.OK,
     51          //                  MessageBoxIcon.Warning);
     52          //  Application.EnableVisualStyles();
     53          //  Application.SetCompatibleTextRenderingDefault(false);
     54          //  Application.Run(new MainForm());
     55          //} else {
     56          //  PluginManager.Manager.Run(app);
     57          //}
    5858        }
    5959      }
Note: See TracChangeset for help on using the changeset viewer.