Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
05/24/19 12:28:29 (6 years ago)
Author:
dpiringe
Message:

#2924:

  • merged projects HeuristicLab.PluginInfrastructure.Runner and HeuristicLab.PluginInfrastructure
  • applied changes of code reviews (13.05.2019 and 22.05.2019) -> the old Runner is now RunnerHost and uses a Runner, which is executed on the child process
  • added Type GetType(string) to IApplicationManager and implemented it for LightweightApplicationManager
  • removed IActivator and IActivatorContext
  • deleted unused types like PluginDescriptionIterator
Location:
branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3
Files:
11 added
8 deleted
9 edited
3 copied
3 moved

Legend:

Unmodified
Added
Removed
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/ApplicationBase.cs

    r13341 r16984  
    2121
    2222
     23using System;
     24
    2325namespace HeuristicLab.PluginInfrastructure {
    2426  /// <summary>
    2527  /// Abstract base implementation for the IApplication interface.
    2628  /// </summary>
     29  [Serializable]
    2730  public abstract class ApplicationBase : IApplication {
    2831    /// <summary>
     
    6972    public abstract void Run(ICommandLineArgument[] args);
    7073
     74    public virtual void OnCancel() { Console.WriteLine("OnCancellation"); }
     75    public virtual void OnPause() { Console.WriteLine("OnPause"); }
     76    public virtual void OnResume() { Console.WriteLine("OnResume"); }
     77
    7178    #endregion
    7279  }
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/ApplicationDescription.cs

    r13389 r16984  
    2626  /// Class that provides information about an application.
    2727  /// </summary>
    28   [Serializable]
     28  /*[Serializable]
    2929  public sealed class ApplicationDescription : IApplicationDescription {
    3030    private string name;
     
    8686      return Name + " " + Version;
    8787    }
    88   }
     88  }*/
    8989}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/HeuristicLab.PluginInfrastructure-3.3.csproj

    r16859 r16984  
    1919    <PackageReference Include="System.CodeDom" Version="4.5.0" />
    2020    <PackageReference Include="System.Drawing.Common" Version="4.5.1" />
     21    <PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
    2122    <PackageReference Include="System.Security.Cryptography.ProtectedData" Version="4.5.0" />
    2223    <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
     
    2425    <PackageReference Include="System.Security.Cryptography.Primitives" Version="4.3.0" />
    2526  </ItemGroup>
     27  <ItemGroup>
     28    <Folder Include="Exceptions\" />
     29  </ItemGroup>
    2630</Project>
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Interfaces/IApplication.cs

    r15973 r16984  
    3838    /// </summary>
    3939    void Run(ICommandLineArgument[] args);
     40
     41    /// <summary>
     42    /// This method gets called when a cancellation is invoked.
     43    /// </summary>
     44    void OnCancel();
     45
     46    /// <summary>
     47    /// This method gets called when a pause is invoked.
     48    /// </summary>
     49    void OnPause();
     50
     51    /// <summary>
     52    /// This method gets called when a resume is invoked.
     53    /// </summary>
     54    void OnResume();
    4055  }
    4156}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Interfaces/IApplicationManager.cs

    r15973 r16984  
    5252    /// <returns>An enumerable of instances of the discovered types.</returns>
    5353    IEnumerable<object> GetInstances(Type type);
     54
     55    /// <summary>
     56    /// Discovers a specific type by its name.
     57    /// </summary>
     58    /// <param name="typeName">Full name of the type.</param>
     59    /// <returns>A type or null, if nothing was found.</returns>
     60    Type GetType(string typeName);
    5461
    5562    /// <summary>
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Interfaces/IAssemblyLoader.cs

    r16859 r16984  
    22using System.Collections.Generic;
    33using System.Reflection;
    4 using System.Text;
    54
    65namespace HeuristicLab.PluginInfrastructure {
     6  /// <summary>
     7  /// Interface for an assembly loading mechanism
     8  /// </summary>
    79  public interface IAssemblyLoader {
    8     string BasePath { get; set; }
    9 
    1010    /// <summary>
    1111    /// Returns all loaded assemblies.
    1212    /// </summary>
    1313    IEnumerable<Assembly> Assemblies { get; }
     14
    1415    /// <summary>
    1516    /// Returns all types.
     
    1819
    1920    /// <summary>
    20     /// Returns all assemblies included in BasePath.
     21    /// Loads all assemblies (.dll/.exe) in the specified path.
    2122    /// </summary>
    22     /// <returns></returns>
    23     IEnumerable<Assembly> GetReflectionOnlyAssemblies();
     23    /// <param name="basePath">Path to root directory of all assemblies to load.</param>
     24    /// <returns>An IEnumerable of assemblies.</returns>
     25    IEnumerable<Assembly> LoadAssemblies(string basePath);
    2426
    2527    /// <summary>
    26     /// Loads all assembliesm which are given by the assemblyName argument, into the current context.
     28    /// Loads all specified assemblies.
    2729    /// </summary>
    28     /// <param name="assemblyNames"></param>
    29     /// <returns>All loaded assemblies.</returns>
    30     IEnumerable<Assembly> LoadAssemblies(IEnumerable<AssemblyName> assemblyNames);
    31 
     30    /// <param name="assemblyInfos">Infos for all assemblies to load.</param>
     31    /// <returns>An IEnumerable of assemblies.</returns>
     32    IEnumerable<Assembly> LoadAssemblies(IEnumerable<AssemblyInfo> assemblyInfos);
    3233  }
    3334}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Interfaces/IPluginLoader.cs

    r16859 r16984  
    1 using System;
    2 using System.Collections.Generic;
    3 using System.Text;
    4 using HeuristicLab.PluginInfrastructure;
     1using System.Collections.Generic;
    52
    63namespace HeuristicLab.PluginInfrastructure {
     4  /// <summary>
     5  /// Interface for a plugin load mechanism.
     6  /// </summary>
    77  public interface IPluginLoader {
    8     /// <summary>
    9     /// Returns all activators found.
    10     /// </summary>
    11     IList<IActivator> Activators { get; }
    12 
    138    /// <summary>
    149    /// Returns all plugins found.
    1510    /// </summary>
    16     IList<IPlugin> Plugins { get; }
     11    IEnumerable<IPlugin> Plugins { get; }
    1712
    1813    /// <summary>
    1914    /// Returns all Applications found.
    2015    /// </summary>
    21     IList<IApplication> Applications { get; }
     16    IEnumerable<IApplication> Applications { get; }
     17
     18    /// <summary>
     19    /// Load plugins, definied by the given AssemblyInfos.
     20    /// </summary>
     21    /// <param name="assemblyInfos">AssemblyInfos for the assemblies, which should be loaded.</param>
     22    void LoadPlugins(IEnumerable<AssemblyInfo> assemblyInfos);
     23
     24    /// <summary>
     25    /// Searches for .dll/.exe files and validates them.
     26    /// </summary>
     27    /// <param name="basePath">Path of the root directory for the assemblies to validate.</param>
     28    /// <returns>A IEnumerable of AssemblyInfos, which contains all loadable assemblies. </returns>
     29    IEnumerable<AssemblyInfo> Validate(string basePath);
    2230  }
    2331}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Interfaces/IRunner.cs

    r16859 r16984  
    11using System;
    22using System.Collections.Generic;
     3using System.IO;
    34using System.Text;
    45
    56namespace HeuristicLab.PluginInfrastructure {
    6 
    7   /// <summary>
    8   /// Interface for all runner implementations.
    9   /// </summary>
    107  public interface IRunner {
    118    /// <summary>
    12     /// Method to start the runner which scans all assemblies in the given basePath argument.
    13     /// Additionally, arguments can be specified, which are forwarded to all activators.
     9    /// Set this to true, if console output should be disabled.
    1410    /// </summary>
    15     /// <param name="basePath"></param>
    16     /// <param name="args"></param>
    17     void Start(string basePath, string[] args);
     11    bool QuietMode { get; set; }
    1812
    19     void Stop();
     13    /// <summary>
     14    /// Assemblies which the child process needs to load.
     15    /// </summary>
     16    IEnumerable<AssemblyInfo> AssembliesToLoad { get; set; }
     17
     18    /// <summary>
     19    /// Method to run the runner.
     20    /// </summary>
     21    void Run();
    2022  }
    2123}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Isolation/AssemblyLoader.cs

    r16983 r16984  
    11using System;
    2 using System.Linq;
    32using System.Collections.Generic;
    43using System.IO;
     4using System.Linq;
    55using System.Reflection;
    66using System.Runtime.Loader;
    7 using System.Runtime.Versioning;
    8 using System.Threading.Tasks;
    97
    10 namespace HeuristicLab.PluginInfrastructure.Runner {
     8namespace HeuristicLab.PluginInfrastructure {
    119
     10  /// <summary>
     11  /// Class to load assemblies.
     12  /// </summary>
    1213  public class AssemblyLoader : IAssemblyLoader {
     14    /// <summary>
     15    /// Comparer for AssemblyNames.
     16    /// </summary>
    1317    private class AssemblyNameComparer : IEqualityComparer<AssemblyName> {
    1418      private object concatProps(AssemblyName name) => name.FullName + name.Version.ToString();
     
    1721    }
    1822
    19     //https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/assemblyloadcontext.md
    20     private class ALC : AssemblyLoadContext {
    21       private Dictionary<AssemblyName, Assembly> loadedAssemblies = new Dictionary<AssemblyName, Assembly>(new AssemblyNameComparer());
    22       private string BasePath { get; set; }
    23       public ALC(string basePath) { BasePath = basePath; }
    24       protected override Assembly Load(AssemblyName assemblyName) {
    25         if (loadedAssemblies.ContainsKey(assemblyName)) return loadedAssemblies[assemblyName];
     23    #region Vars
     24    private readonly IList<Assembly> assemblies = new List<Assembly>();
     25    private readonly IList<Type> types = new List<Type>();
     26    #endregion
    2627
    27         string path = $"{BasePath}{Path.DirectorySeparatorChar}{assemblyName.Name}.dll";
    28         Assembly asm = null;
    29         if (File.Exists(path))
    30           asm = Assembly.LoadFrom(path);
    31         else
    32           asm = Assembly.Load(assemblyName);
    33         loadedAssemblies.Add(assemblyName, asm);
    34         foreach (var a in asm.GetReferencedAssemblies())
    35           Load(a);
    36         return asm;
    37       }
    38     }
    39 
    40     private ALC alc;
    41     public string BasePath { get; set; }
    42     public string AssemblyPrefix { get; set; }
    43 
    44     //public IList<Assembly> Assemblies { private set; get; } = new List<Assembly>();
    45     //public IList<Type> Types { private set; get; } = new List<Type>();
    46 
    47     private IList<Assembly> assemblies = new List<Assembly>();
     28    #region Properties
     29    /// <summary>
     30    /// All loaded assemblies. Contains items only after a call of LoadAssemblies.
     31    /// </summary>
    4832    public IEnumerable<Assembly> Assemblies => assemblies;
    4933
    50     private IList<Type> types = new List<Type>();
     34    /// <summary>
     35    /// All types found in all assemblies.
     36    /// </summary>
    5137    public IEnumerable<Type> Types => types;
     38    #endregion
    5239
    53     public AssemblyLoader() : this(Directory.GetCurrentDirectory()) { }
    54     public AssemblyLoader(string basePath) {
    55       this.BasePath = basePath;
    56       alc = new ALC(BasePath);
     40    #region Constructors
     41    public AssemblyLoader() {
     42
     43      #region alternative code
    5744      /*
    5845      ScanTypesInBasePath();
     
    6754      //LoadAssemblies(asms);
    6855      //LoadTypes(asms);
     56      #endregion
     57    }
     58    #endregion
     59
     60
     61    private IEnumerable<string> GetAssembliesFromBasePath(string basePath) {
     62      return Directory.GetFiles(basePath, "*.dll", SearchOption.AllDirectories)
     63        .Concat(Directory.GetFiles(basePath, "*.exe", SearchOption.AllDirectories));
    6964    }
    7065
    71     // 1.
    72     private IEnumerable<string> GetAssembliesFromBasePath() {
    73       return Directory.GetFiles(BasePath, $"*.dll", SearchOption.AllDirectories);
    74     }
     66    #region alternative code
    7567    /*
    7668    // 2.
     
    126118    }
    127119    */
     120    #endregion
     121
     122
    128123    private void LoadTypes(IEnumerable<Assembly> assemblies) {
    129124      foreach (Assembly asm in assemblies) {
     
    133128          }
    134129        } catch (ReflectionTypeLoadException e) {
     130          // ReflectionTypeLoadException gets thrown if any class in a module cannot be loaded.
    135131          try {
    136             foreach (Type t in e.Types) {
     132            foreach (Type t in e.Types) { // fetch the already loaded types, be careful some of them can be null
    137133              if (t != null) {
    138134                types.Add(t);
     
    140136            }
    141137          } catch (BadImageFormatException) { }
    142 
    143         } catch (Exception e) {
    144           Tracing.Logger.Error(
    145             $"Exception occured while loading types of assembly {asm.FullName}! \n " +
    146             $"---- Stacktrace ---- \n {e}");
     138        } catch (Exception e) { // to catch every other exception
     139          //Tracing.Logger.Error(
     140          //  $"Exception occured while loading types of assembly {asm.FullName}! \n " +
     141          //  $"---- Stacktrace ---- \n {e}");
    147142        }
    148143      }
    149144    }
    150     /*
    151     public Type GetType(string type) {
    152       foreach (Assembly asm in Assemblies) {
    153         Type t = asm.GetType(type);
    154         if (t != null) return t;
    155       }
    156       return null;
    157     }
    158     */
    159145
    160     public IEnumerable<Assembly> GetReflectionOnlyAssemblies() {
    161       IList<Assembly> list = new List<Assembly>();
    162       foreach (string path in GetAssembliesFromBasePath()) {
    163         try {
    164           var asm = Assembly.LoadFrom(path);
    165           if (asm != null)
    166             list.Add(asm);
    167           else
    168             Tracing.Logger.Error($"Unnable to load assembly with path {path}!");
    169         } catch (Exception e) {
    170           Tracing.Logger.Error(
    171             $"Exception occured while loading assembly from path {path}! \n " +
    172             $"---- Stacktrace ---- \n {e}");
    173         }
    174       }
    175       return list;
    176     }
    177 
    178     public IEnumerable<Assembly> LoadAssemblies(IEnumerable<AssemblyName> assemblyNames) {
    179       foreach (AssemblyName asm in assemblyNames) {
    180         try {
    181           this.assemblies.Add(alc.LoadFromAssemblyName(asm));
    182         } catch (Exception e) {
    183           Tracing.Logger.Error(
    184             $"Exception occured while loading assembly: {asm.FullName}! \n " +
    185             $"---- Stacktrace ---- \n {e}");
    186         }
    187       }
     146    public IEnumerable<Assembly> LoadAssemblies(string basePath) {
     147      foreach (string path in GetAssembliesFromBasePath(basePath))
     148        LoadAssemblyFromPath(path);
     149     
    188150      LoadTypes(this.Assemblies);
    189151      return this.Assemblies;
    190152    }
     153
     154    public IEnumerable<Assembly> LoadAssemblies(IEnumerable<AssemblyInfo> assemblyInfos) {
     155      foreach (var info in assemblyInfos)
     156        LoadAssemblyFromPath(info.Path.ToString());
     157     
     158      LoadTypes(this.Assemblies);
     159      return this.Assemblies;
     160    }
     161
     162    private void LoadAssemblyFromPath(string path) {
     163      try {
     164        var asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(path); // loads assembly into default context
     165        if (asm != null) {
     166          assemblies.Add(asm);
     167        } // else
     168          //Tracing.Logger.Error($"Unnable to load assembly with path {path}!");
     169      } catch (Exception e) { // to catch every exception occured by assembly loading.
     170        //Tracing.Logger.Error(
     171        //  $"Exception occured while loading assembly from path {path}! \n " +
     172        //  $"---- Stacktrace ---- \n {e}");
     173      }
     174    }
    191175  }
    192176}
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Isolation/PluginLoader.cs

    r16983 r16984  
    11using System;
     2using System.Collections.Generic;
     3using System.IO;
    24using System.Linq;
    3 using System.Collections.Generic;
     5using System.Reflection;
     6using System.Security;
    47using System.Text;
    5 using HeuristicLab.PluginInfrastructure;
    6 using System.Reflection;
    7 using System.IO;
    8 using System.Security;
    9 
    10 namespace HeuristicLab.PluginInfrastructure.Runner {
    11   internal class PluginLoader : IPluginLoader {
    12 
     8
     9namespace HeuristicLab.PluginInfrastructure {
     10  public class PluginLoader : IPluginLoader {
     11
     12    /// <summary>
     13    /// Helper class for depedency metadata.
     14    /// </summary>
    1315    private class PluginDependency {
    1416      public string Name { get; private set; }
    1517      public Version Version { get; private set; }
    16 
    1718      public PluginDependency(string name, Version version) {
    1819        this.Name = name;
     
    2122    }
    2223
    23     private IList<IPlugin> plugins = null;
    24     public IList<IPlugin> Plugins {
    25       private set => plugins = value;
    26       get {
    27         if (plugins == null) {
    28           Plugins = new List<IPlugin>();
    29           DiscoverPlugins();
    30         }
    31         return plugins;
    32       }
    33     }
    34 
    35     private IList<IApplication> applications = null;
    36     public IList<IApplication> Applications {
    37       private set => applications = value;
    38       get {
    39         if (applications == null) {
    40           Applications = new List<IApplication>();
    41           DiscoverApplications();
    42         }
    43         return applications;
    44       }
    45     }
    46 
    47     private IList<IActivator> activators = null;
    48     public IList<IActivator> Activators {
    49       private set => activators = value;
    50       get {
    51         if (activators == null) {
    52           activators = new List<IActivator>();
    53           DiscoverActivators();
    54         }
    55         return activators;
    56       }
    57     }
    58 
    59 
    60     #region oldCode
     24    #region Vars
     25    private IList<IPlugin> plugins = new List<IPlugin>();
     26    private IList<IApplication> applications = new List<IApplication>();
     27    private IAssemblyLoader assemblyLoader = null;
    6128    private Dictionary<PluginDescription, IEnumerable<PluginDependency>> pluginDependencies = new Dictionary<PluginDescription, IEnumerable<PluginDependency>>();
    6229    #endregion
    63     private IEnumerable<Assembly> reflectionOnlyAssemblies;
    64     private IAssemblyLoader asmLoader;
    65     private string BasePath { get; set; }
    66 
    67     public PluginLoader(string basePath, IAssemblyLoader assemblyLoader) {
    68       asmLoader = assemblyLoader;
    69       this.BasePath = basePath;
    70       Init();
    71     }
    72 
    73     private void Init() {
    74       reflectionOnlyAssemblies = asmLoader.GetReflectionOnlyAssemblies();
    75 
    76       IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(reflectionOnlyAssemblies);
    77 
    78 
    79       CheckPluginFiles(pluginDescriptions);
     30
     31    #region Properties
     32    public IEnumerable<IPlugin> Plugins => plugins;
     33
     34    public IEnumerable<IApplication> Applications => applications;
     35    #endregion
     36
     37    #region Constructors
     38    public PluginLoader(IAssemblyLoader assemblyLoader) {
     39      this.assemblyLoader = assemblyLoader;
     40    }
     41    #endregion
     42
     43    #region Discover Methods
     44    public void LoadPlugins(IEnumerable<AssemblyInfo> assemblyInfos) {
     45      assemblyLoader.LoadAssemblies(assemblyInfos);
     46      DiscoverPlugins();
     47      DiscoverApplications();
     48    }
     49    /// <summary>
     50    /// Discovers all types of IPlugin of all loaded assemblies. Saves the found plugins in a list.
     51    /// </summary>
     52    private void DiscoverPlugins() {
     53      // search plugins out of all types
     54      string curDir = Directory.GetCurrentDirectory(); // save current working directory
     55      foreach (var type in assemblyLoader.Types) {
     56        if (typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && !type.HasElementType) {
     57          // to set the working directory to the assembly location, this is necessary for assemblies which load data in the OnLoad method by their own.
     58          // example: HeuristicLabMathJaxPlugin
     59          Directory.SetCurrentDirectory(type.Assembly.Location.Replace(Path.GetFileName(type.Assembly.Location), ""));
     60          IPlugin p = (IPlugin)Activator.CreateInstance(type);
     61          p.OnLoad();
     62          plugins.Add(p);
     63        }
     64      }
     65      Directory.SetCurrentDirectory(curDir); // set working directory to its base value
     66    }
     67
     68    /// <summary>
     69    /// Discovers all types of IApplication of all loaded assemblies. Saves the found applications in a list.
     70    /// </summary>
     71    private void DiscoverApplications() {
     72      foreach (Type type in assemblyLoader.Types) {
     73        if (typeof(IApplication).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && !type.HasElementType) {
     74          IApplication app = (IApplication)Activator.CreateInstance(type);
     75          applications.Add(app);
     76        }
     77      }
     78    }
     79    #endregion
     80       
     81    public IEnumerable<AssemblyInfo> Validate(string basePath) {
     82      IEnumerable<Assembly> assemblies = assemblyLoader.LoadAssemblies(basePath);
     83
     84      IList<PluginDescription> pluginDescriptions = GatherPluginDescriptions(assemblies, basePath);
     85      CheckPluginFiles(pluginDescriptions, basePath);
    8086
    8187      // check if all plugin assemblies can be loaded
    82       CheckPluginAssemblies(pluginDescriptions);
     88      CheckPluginAssemblies(assemblies, pluginDescriptions);
    8389
    8490      // a full list of plugin descriptions is available now we can build the dependency tree
     
    9399      // in the next step
    94100      CheckPluginDependencies(pluginDescriptions);
    95       // load assemblies
    96       IEnumerable<Assembly> assemblies = asmLoader.LoadAssemblies(
    97         pluginDescriptions
    98         .Where(x => x.PluginState != PluginState.Disabled)
    99         .SelectMany(
    100           x => x.AssemblyLocations
    101           .SelectMany(loc =>
    102             reflectionOnlyAssemblies
    103             .Where(asm => string.Equals(Path.GetFullPath(asm.Location), Path.GetFullPath(loc), StringComparison.CurrentCultureIgnoreCase))
    104             .Select(asm => asm.GetName())
    105           )
    106         )
    107       );
    108     }
    109 
    110     private void DiscoverPlugins() {
    111       // search plugins out of all types
    112       foreach (var type in asmLoader.Types) {
    113         if (typeof(IPlugin).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && !type.HasElementType) {
    114           IPlugin p = (IPlugin)Activator.CreateInstance(type);
    115           //p.OnLoad();
    116           Plugins.Add(p);
    117         }
    118       }
    119 
    120       #region oldCode
    121       /*
    122       IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(asmLoader.Assemblies);
    123      
    124       CheckPluginFiles(pluginDescriptions);
    125       //--> checken ob alle assemblies physisch vorliegen die benötigt werden (depedency)
    126 
    127       // check if all plugin assemblies can be loaded
    128       CheckPluginAssemblies(pluginDescriptions); //--> ob sie auch geladen werden können
    129       //--> 1. und 2. könnte man zusammenfassen, da eh schon assemblies gescannt und geladen wurden ... checken ob diese vorliegen -> asmLoader.Assemblies
    130 
    131       // a full list of plugin descriptions is available now we can build the dependency tree
    132       BuildDependencyTree(pluginDescriptions); //--> gleich auf assembly basis?!
    133 
    134       // check for dependency cycles
    135       CheckPluginDependencyCycles(pluginDescriptions);
    136 
    137       // 1st time recursively check if all necessary plugins are available and not disabled
    138       // disable plugins with missing or disabled dependencies
    139       // to prevent that plugins with missing dependencies are loaded into the execution context
    140       // in the next step
    141       CheckPluginDependencies(pluginDescriptions); //--> "disabled" assemblies merken (evtl. mit Dictionary)
    142 
    143       // test full loading (in contrast to reflection only loading) of plugins
    144       // disables plugins that are not loaded correctly
    145       CheckExecutionContextLoad(pluginDescriptions);
    146 
    147       // 2nd time recursively check if all necessary plugins have been loaded successfully and not disabled
    148       // disable plugins with for which dependencies could not be loaded successfully
    149       CheckPluginDependencies(pluginDescriptions);
    150      
    151       foreach (var desc in pluginDescriptions)
    152         if (desc.PluginState != PluginState.Disabled)
    153           desc.Enable();
    154 
    155       // load the enabled plugins
    156       LoadPlugins(pluginDescriptions);
    157       */
    158       #endregion
    159     }
    160 
    161     private void DiscoverApplications() {
    162       foreach (Type type in asmLoader.Types) {
    163         if (typeof(IApplication).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && !type.HasElementType) {
    164           IApplication app = (IApplication)Activator.CreateInstance(type);
    165           Applications.Add(app);
    166         }
    167       }
    168     }
    169 
    170     private void DiscoverActivators() {
    171       foreach (Type type in asmLoader.Types) {
    172         if (typeof(IActivator).IsAssignableFrom(type) && !type.IsAbstract && !type.IsInterface && !type.HasElementType) {
    173           IActivator act = (IActivator)Activator.CreateInstance(type);
    174           Activators.Add(act);
    175         }
    176       }
     101
     102      // build assemblyInfo list:
     103      // 1.) iterate through pluginDescriptions and pick all not disabled plugins
     104      // 2.) iterate through the assemblyLocations, saved in a description
     105      // 3.) iterate thorugh all loaded assemblies
     106      // 4.) if the location of an assemblies and a pluginDescriptions match -> create new AssemblyInfo and add it to a list
     107      IList<AssemblyInfo> list = new List<AssemblyInfo>();
     108      foreach (var desc in pluginDescriptions) {
     109        if (desc.PluginState != PluginState.Disabled) {
     110          foreach (var loc in desc.AssemblyLocations) {
     111            foreach (var asm in assemblies) {
     112              if (string.Equals(Path.GetFullPath(asm.Location), Path.GetFullPath(loc), StringComparison.CurrentCultureIgnoreCase))
     113                list.Add(new AssemblyInfo() { Path = new UniPath(asm.Location), Name = asm.FullName });
     114            }
     115          }
     116        }
     117      }
     118
     119      return list;
    177120    }
    178121
     
    182125    /// </summary>
    183126    /// <param name="pluginDescriptions"></param>
    184     private void CheckPluginAssemblies(IEnumerable<PluginDescription> pluginDescriptions) {
     127    private void CheckPluginAssemblies(IEnumerable<Assembly> assemblies, IEnumerable<PluginDescription> pluginDescriptions) {
    185128      foreach (var desc in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
    186129        try {
     
    190133            // so we simply determine the name of the assembly and try to find it in the cache of loaded assemblies
    191134            var asmName = AssemblyName.GetAssemblyName(asmLocation);
    192             if (!reflectionOnlyAssemblies.Select(x => x.GetName().FullName).Contains(asmName.FullName)) {
     135            if (!assemblies.Select(x => x.GetName().FullName).Contains(asmName.FullName)) {
    193136              missingAssemblies.Add(asmName.FullName);
    194137            }
     
    225168    // the dependencies in the plugin descriptions are not yet set correctly because we need to create
    226169    // the full list of all plugin descriptions first
    227     private IEnumerable<PluginDescription> GatherPluginDescriptions(IEnumerable<Assembly> assemblies) {
     170    private IList<PluginDescription> GatherPluginDescriptions(IEnumerable<Assembly> assemblies, string basePath) {
    228171      List<PluginDescription> pluginDescriptions = new List<PluginDescription>();
    229172      foreach (Assembly assembly in assemblies) {
     
    234177          // use AssemblyQualifiedName to compare the types because we can't directly
    235178          // compare ReflectionOnly types and execution types
     179
    236180          var assemblyPluginDescriptions = from t in assembly.GetExportedTypes()
    237181                                           where !t.IsAbstract && t.GetInterfaces()
    238182                                           .Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)
    239                                            select GetPluginDescription(t);
     183                                           select GetPluginDescription(t, basePath);
    240184          pluginDescriptions.AddRange(assemblyPluginDescriptions);
    241185        }
     
    252196
    253197    // checks if all declared plugin files are actually available and disables plugins with missing files
    254     private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
     198    private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions, string basePath) {
    255199      foreach (PluginDescription desc in pluginDescriptions) {
    256200        IEnumerable<string> missingFiles;
    257         if (ArePluginFilesMissing(desc, out missingFiles)) {
     201        if (ArePluginFilesMissing(desc, basePath, out missingFiles)) {
    258202          StringBuilder errorStrBuilder = new StringBuilder();
    259203          errorStrBuilder.AppendLine("Missing files:");
     
    266210    }
    267211
    268     private bool ArePluginFilesMissing(PluginDescription pluginDescription, out IEnumerable<string> missingFiles) {
     212    private bool ArePluginFilesMissing(PluginDescription pluginDescription, string basePath, out IEnumerable<string> missingFiles) {
    269213      List<string> missing = new List<string>();
    270214      foreach (string filename in pluginDescription.Files.Select(x => x.Name)) {
    271         if (!FileLiesInDirectory(BasePath, filename) ||
     215        if (!FileLiesInDirectory(basePath, filename) ||
    272216          !File.Exists(filename)) {
    273217          missing.Add(filename);
     
    289233    /// </summary>
    290234    /// <param name="pluginType"></param>
    291     private PluginDescription GetPluginDescription(Type pluginType) {
     235    private PluginDescription GetPluginDescription(Type pluginType, string basePath) {
    292236
    293237      string pluginName, pluginDescription, pluginVersion;
     
    295239      GetPluginMetaData(pluginType, out pluginName, out pluginDescription, out pluginVersion);
    296240      GetPluginContactMetaData(pluginType, out contactName, out contactAddress);
    297       var pluginFiles = GetPluginFilesMetaData(pluginType);
     241      var pluginFiles = GetPluginFilesMetaData(pluginType, basePath);
    298242      var pluginDependencies = GetPluginDependencyMetaData(pluginType);
    299243
     
    373317
    374318    // not static because we need the BasePath property
    375     private IEnumerable<PluginFile> GetPluginFilesMetaData(Type pluginType) {
     319    private IEnumerable<PluginFile> GetPluginFilesMetaData(Type pluginType, string basePath) {
    376320      // get all attributes of type PluginFileAttribute
    377321      var pluginFileAttributes = from attr in CustomAttributeData.GetCustomAttributes(pluginType)
     
    381325        string pluginFileName = (string)pluginFileAttribute.ConstructorArguments[0].Value;
    382326        PluginFileType fileType = (PluginFileType)pluginFileAttribute.ConstructorArguments[1].Value;
    383         yield return new PluginFile(Path.GetFullPath(Path.Combine(BasePath, pluginFileName)), fileType);
     327        yield return new PluginFile(Path.GetFullPath(Path.Combine(basePath, pluginFileName)), fileType);
    384328      }
    385329    }
     
    405349      }
    406350    }
     351
    407352
    408353    private static bool IsAttributeDataForType(CustomAttributeData attributeData, Type attributeType) {
     
    496441    }
    497442
    498 
    499443    private bool IsAnyDependencyDisabled(PluginDescription descr, List<PluginDescription> disabledPlugins) {
    500444      if (descr.PluginState == PluginState.Disabled) {
     
    507451      return disabledPlugins.Count > 0;
    508452    }
    509 
    510     // tries to load all plugin assemblies into the execution context
    511     // if an assembly of a plugin cannot be loaded the plugin is disabled
    512     private void CheckExecutionContextLoad(IEnumerable<PluginDescription> pluginDescriptions) {
    513       // load all loadable plugins (all dependencies available) into the execution context
    514       foreach (var desc in PluginDescriptionIterator.IterateDependenciesBottomUp(pluginDescriptions
    515                                                                                 .Where(x => x.PluginState != PluginState.Disabled))) {
    516         // store the assembly names so that we can later retrieve the assemblies loaded in the appdomain by name
    517         var assemblyNames = new List<string>();
    518         foreach (string assemblyLocation in desc.AssemblyLocations) {
    519           if (desc.PluginState != PluginState.Disabled) {
    520             try {
    521               string assemblyName = (from assembly in asmLoader.Assemblies//AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies()
    522                                      where string.Equals(Path.GetFullPath(assembly.Location), Path.GetFullPath(assemblyLocation), StringComparison.CurrentCultureIgnoreCase)
    523                                      select assembly.FullName).Single();
    524               // now load the assemblies into the execution context 
    525               // this can still lead to an exception
    526               // even when the assemby was successfully loaded into the reflection only context before
    527               // when loading the assembly using it's assemblyName it can be loaded from a different location than before (e.g. the GAC)
    528               //Assembly.Load(assemblyName);
    529               assemblyNames.Add(assemblyName);
    530             } catch (BadImageFormatException) {
    531               desc.Disable(Path.GetFileName(assemblyLocation) + " is not a valid assembly.");
    532             } catch (FileLoadException) {
    533               desc.Disable("Can't load file " + Path.GetFileName(assemblyLocation));
    534             } catch (FileNotFoundException) {
    535               desc.Disable("File " + Path.GetFileName(assemblyLocation) + " is missing.");
    536             } catch (SecurityException) {
    537               desc.Disable("File " + Path.GetFileName(assemblyLocation) + " can't be loaded because of security constraints.");
    538             } catch (NotSupportedException ex) {
    539               // disable the plugin
    540               desc.Disable("Problem while loading plugin assemblies:" + Environment.NewLine + "NotSupportedException: " + ex.Message);
    541             }
    542           }
    543         }
    544         desc.AssemblyNames = assemblyNames;
    545       }
    546     }
    547 
    548     // assumes that all plugin assemblies have been loaded into the execution context via CheckExecutionContextLoad
    549     // for each enabled plugin:
    550     // calls OnLoad method of the plugin
    551     // and raises the PluginLoaded event
    552     private void LoadPlugins(IEnumerable<PluginDescription> pluginDescriptions) {
    553       List<Assembly> assemblies = new List<Assembly>(asmLoader.Assemblies);
    554       plugins = new List<IPlugin>();
    555       foreach (var desc in pluginDescriptions) {
    556         if (desc.PluginState == PluginState.Enabled) {
    557           // cannot use ApplicationManager to retrieve types because it is not yet instantiated
    558           foreach (string assemblyName in desc.AssemblyNames) {
    559             var asm = (from assembly in assemblies
    560                        where assembly.FullName == assemblyName
    561                        select assembly)
    562                       .SingleOrDefault();
    563             if (asm == null) throw new InvalidPluginException("Could not load assembly " + assemblyName + " for plugin " + desc.Name);
    564             foreach (Type pluginType in asm.GetExportedTypes()) {
    565               if (typeof(IPlugin).IsAssignableFrom(pluginType) && !pluginType.IsAbstract && !pluginType.IsInterface && !pluginType.HasElementType) {
    566                 IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
    567                 plugin.OnLoad();
    568                 plugins.Add(plugin);
    569                 //OnPluginLoaded(new PluginInfrastructureEventArgs(desc));
    570               }
    571             }
    572           } // end foreach assembly in plugin
    573           desc.Load();
    574         }
    575       } // end foreach plugin description
    576     }
    577453  }
    578454  #endregion
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Isolation/PluginLoaderFactory.cs

    r16983 r16984  
    44using System.Text;
    55
    6 namespace HeuristicLab.PluginInfrastructure.Runner {
    7   public class PluginLoaderFactory {
     6namespace HeuristicLab.PluginInfrastructure {
     7  /// <summary>
     8  /// Factory to create an instance of a plugin loader.
     9  /// </summary>
     10  public static class PluginLoaderFactory {
     11    /// <summary>
     12    /// Creates a new instance of a plugin loader.
     13    /// </summary>
    814    public static IPluginLoader Create() {
    9       return Create(Directory.GetCurrentDirectory());
    10     }
    11 
    12     internal static IPluginLoader Create(string basePath) {
    13       return new PluginLoader(basePath, new AssemblyLoader(basePath));
     15      return new PluginLoader(new AssemblyLoader());
    1416    }
    1517  }
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/LightweightApplicationManager.cs

    r15973 r16984  
    7575      foreach (Type t in GetTypes(type)) {
    7676        object instance = null;
    77         try { instance = Activator.CreateInstance(t); }
    78         catch { }
     77        try { instance = Activator.CreateInstance(t); } catch { }
    7978        if (instance != null) instances.Add(instance);
    8079      }
    8180      return instances;
     81    }
     82
     83    public Type GetType(string typeName) {
     84      foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
     85        Type t = asm.GetType(typeName);
     86        if (t != null) return t;
     87      }
     88      return null;
    8289    }
    8390
     
    126133        // necessary to make sure the exception is immediately thrown
    127134        // instead of later when the enumerable is iterated?
     135
    128136        var assemblyTypes = assembly.GetTypes();
    129137
     
    138146
    139147        return matchingTypes;
    140       }
    141       catch (TypeLoadException) {
     148      } catch (TypeLoadException) {
    142149        return Enumerable.Empty<Type>();
    143       }
    144       catch (ReflectionTypeLoadException) {
     150      } catch (ReflectionTypeLoadException) {
    145151        return Enumerable.Empty<Type>();
    146152      }
Note: See TracChangeset for help on using the changeset viewer.