Free cookie consent management tool by TermsFeed Policy Generator

Changeset 2690


Ignore:
Timestamp:
01/27/10 17:08:03 (15 years ago)
Author:
gkronber
Message:

Fixed caching and resolve event handler in plugin infrastructure to fix the bug that the SqlServerCompact assembly is not found when opening a db connection. #854 (System.Data.SqlServerCe assembly is not loaded correctly)

Location:
trunk/sources/HeuristicLab.PluginInfrastructure
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.PluginInfrastructure/Advanced/InstallationManager.cs

    r2688 r2690  
    127127            // or there was a problem loading the assemblies
    128128            builder.AppendLine("There was a problem while loading assemblies: ");
    129             foreach (AssemblyName assembly in desc.AssemblyNames) {
    130               builder.AppendLine(assembly.FullName);
     129            foreach (string assemblyLocation in desc.AssemblyLocations) {
     130              builder.AppendLine(assemblyLocation + ": " + AssemblyName.GetAssemblyName(assemblyLocation).FullName);
    131131            }
    132132            return builder.ToString();
  • trunk/sources/HeuristicLab.PluginInfrastructure/ApplicationManager.cs

    r2688 r2690  
    7575      loadedAssemblies = new Dictionary<string, Assembly>();
    7676      loadedPlugins = new List<IPlugin>();
    77       // needed for the special case when assemblies are loaded dynamically via LoadAssemblies()
    7877      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
    7978        if (loadedAssemblies.ContainsKey(args.Name)) {
     
    103102      // load all loadable plugins (all dependencies available) into the execution context
    104103      foreach (var desc in PluginDescriptionIterator.IterateDependenciesBottomUp(plugins.Where(x => x.PluginState != PluginState.Disabled))) {
    105         foreach (AssemblyName assemblyName in desc.AssemblyNames) {
    106           var asm = Assembly.Load(assemblyName);
    107 
     104        foreach (string fileName in desc.AssemblyLocations) {
     105          var asm = Assembly.LoadFrom(fileName);
     106          RegisterLoadedAssembly(asm);
    108107          // instantiate and load all plugins in this assembly
    109108          foreach (var plugin in GetInstances<IPlugin>(asm)) {
     
    213212      PluginDescription pluginDesc = (PluginDescription)pluginDescription;
    214213      return from asm in AppDomain.CurrentDomain.GetAssemblies()
    215              where pluginDesc.AssemblyNames.Any(asmName => asmName.FullName.Equals(asm.GetName().FullName))
     214             where pluginDesc.AssemblyLocations.Any(location => location.Equals(Path.GetFullPath(asm.Location), StringComparison.CurrentCultureIgnoreCase))
    216215             from t in GetTypes(type, asm, onlyInstantiable)
    217216             select t;
     
    283282    public IPluginDescription GetDeclaringPlugin(Type type) {
    284283      foreach (PluginDescription info in Plugins) {
    285         if (info.AssemblyNames.Contains(type.Assembly.GetName())) return info;
     284        if (info.AssemblyLocations.Contains(Path.GetFullPath(type.Assembly.Location))) return info;
    286285      }
    287286      return null;
  • trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginDescription.cs

    r2688 r2690  
    106106    }
    107107
    108     private List<AssemblyName> assemblyNames = new List<AssemblyName>();
     108   
    109109    /// <summary>
    110     /// Gets the names of the assemblies that belong to this plugin.
     110    /// Gets the locations (file names) of the assemblies that belong to this plugin.
    111111    /// </summary>
    112     public IEnumerable<AssemblyName> AssemblyNames {
    113       get { return assemblyNames; }
    114     }
    115 
    116     internal void AddAssemblyNames(IEnumerable<AssemblyName> assemblyNames) {
    117       this.assemblyNames.AddRange(assemblyNames);
     112    public IEnumerable<string> AssemblyLocations {
     113      get { return Files.Where(f => f.Type == PluginFileType.Assembly).Select(f => f.Name); }
    118114    }
    119115
  • trunk/sources/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2688 r2690  
    6868    }
    6969
     70    private Dictionary<string, Assembly> reflectionOnlyAssemblies = new Dictionary<string, Assembly>();
    7071    private Assembly ReflectionOnlyAssemblyResolveEventHandler(object sender, ResolveEventArgs args) {
    71       return Assembly.ReflectionOnlyLoad(args.Name);
     72      if (reflectionOnlyAssemblies.ContainsKey(args.Name))
     73        return reflectionOnlyAssemblies[args.Name];
     74      else
     75        return Assembly.ReflectionOnlyLoad(args.Name);
    7276    }
    7377
     
    147151    }
    148152
    149     private static IEnumerable<Assembly> ReflectionOnlyLoadDlls(string baseDir) {
     153    private IEnumerable<Assembly> ReflectionOnlyLoadDlls(string baseDir) {
    150154      List<Assembly> assemblies = new List<Assembly>();
    151155      // recursively load .dll files in subdirectories
     
    156160      foreach (string filename in Directory.GetFiles(baseDir, "*.dll")) {
    157161        try {
    158           assemblies.Add(Assembly.ReflectionOnlyLoadFrom(filename));
     162          Assembly asm = Assembly.ReflectionOnlyLoadFrom(filename);
     163          RegisterLoadedAssembly(asm);
     164          assemblies.Add(asm);
    159165        }
    160166        catch (BadImageFormatException) { } // just ignore the case that the .dll file is not a CLR assembly (e.g. a native dll)
     
    172178      foreach (var desc in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
    173179        try {
    174           foreach (var asmName in desc.AssemblyNames) {
    175             Assembly.ReflectionOnlyLoad(asmName.FullName);
     180          foreach (var asmLocation in desc.AssemblyLocations) {
     181            // the assembly must have been loaded in ReflectionOnlyDlls
     182            // so we simply determine the name of the assembly and try to find it in the cache of loaded assemblies
     183            var asmName = AssemblyName.GetAssemblyName(asmLocation);
     184
     185            if (!reflectionOnlyAssemblies.ContainsKey(asmName.FullName)) {
     186              desc.Disable();
     187              break; // as soon as one assembly is not available disable the plugin and check the next plugin description
     188            }
    176189          }
    177190        }
     
    237250      // get all attributes of that type
    238251      IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(pluginType);
    239       List<AssemblyName> pluginAssemblyNames = new List<AssemblyName>();
    240252      List<string> pluginDependencies = new List<string>();
    241253      List<PluginFile> pluginFiles = new List<PluginFile>();
     
    255267          PluginFileType fileType = (PluginFileType)attributeData.ConstructorArguments[1].Value;
    256268          pluginFiles.Add(new PluginFile(Path.GetFullPath(Path.Combine(PluginDir, pluginFileName)), fileType));
    257           if (fileType == PluginFileType.Assembly) {
    258             pluginAssemblyNames.Add(AssemblyName.GetAssemblyName(Path.GetFullPath(Path.Combine(PluginDir, pluginFileName))));
    259           }
    260269        }
    261270      }
     
    267276      // minimal sanity check of the attribute values
    268277      if (!string.IsNullOrEmpty(pluginName) &&
    269           pluginFiles.Count > 0 &&
    270           pluginAssemblyNames.Count > 0 &&
    271           buildDates.Count() == 1) {
     278          pluginFiles.Count > 0 &&                                   // at least on file
     279          pluginFiles.Any(f => f.Type == PluginFileType.Assembly) && // at least on assembly
     280          buildDates.Count() == 1) {                                 // build date must be declared
    272281        // create a temporary PluginDescription that contains the attribute values
    273282        PluginDescription info = new PluginDescription();
     
    276285        info.Version = pluginType.Assembly.GetName().Version;
    277286        info.BuildDate = DateTime.Parse(buildDates.Single(), System.Globalization.CultureInfo.InvariantCulture);
    278         info.AddAssemblyNames(pluginAssemblyNames);
    279287        info.AddFiles(pluginFiles);
    280288
     
    349357                                                                                .Where(x => x.PluginState != PluginState.Disabled))) {
    350358        List<Type> types = new List<Type>();
    351         foreach (AssemblyName assemblyName in desc.AssemblyNames) {
    352           var asm = Assembly.Load(assemblyName);
     359        foreach (string assemblyLocation in desc.AssemblyLocations) {
     360          // now load the assemblies into the execution context
     361          var asm = Assembly.LoadFrom(assemblyLocation);
    353362          foreach (Type t in asm.GetTypes()) {
    354363            if (typeof(IPlugin).IsAssignableFrom(t)) {
     
    393402    }
    394403
     404    // register assembly in the assembly cache for the ReflectionOnlyAssemblyResolveEvent
     405    private void RegisterLoadedAssembly(Assembly asm) {
     406      reflectionOnlyAssemblies.Add(asm.FullName, asm);
     407      reflectionOnlyAssemblies.Add(asm.GetName().Name, asm); // add short name
     408    }
     409
    395410    internal void OnPluginLoaded(PluginInfrastructureEventArgs e) {
    396411      if (PluginLoaded != null)
Note: See TracChangeset for help on using the changeset viewer.