/// <summary> /// Loads the module assembly. /// </summary> /// <param name="fileName">The assembly path to load a module from.</param> void LoadModule(string fileName) { Log.Source.TraceInformation("Load module {0}", fileName); // use the file info to reduce file access var fileInfo = new FileInfo(fileName); if (!fileInfo.Exists) { Log.Source.TraceInformation("Module is not found."); return; } // load from the cache if (ReadCache(fileInfo)) { return; } // add new module manager now, it will be removed on errors ModuleManager manager = new ModuleManager(fileInfo.FullName); _Managers.Add(manager.ModuleName, manager); // read and load data var settings = manager.ReadSettings(); manager.LoadData(settings); bool done = false; try { Log.Source.TraceInformation("Load module {0}", manager.ModuleName); int actionCount = 0; Assembly assembly = manager.LoadAssembly(); foreach (Type type in assembly.GetExportedTypes()) { if (typeof(BaseModuleItem).IsAssignableFrom(type) && !type.IsAbstract) { actionCount += LoadType(manager, settings, type); } else if (!manager.HasSettings && typeof(ApplicationSettingsBase).IsAssignableFrom(type) && !type.IsAbstract) { manager.HasSettings = true; } } // if the module has the host to load then load it now, if it is not loaded then the module should be cached if (!manager.LoadLoadableModuleHost()) { if (0 == actionCount) { throw new ModuleException("A module must have a public action or a pre-loadable host."); } SaveModuleCache(manager, fileInfo); } // done done = true; } finally { if (!done) { RemoveModuleManager(manager); } } }
/// <summary> /// Reads the module from the cache. /// </summary> /// <param name="fileInfo">Module file information.</param> /// <returns>True if the module has been loaded from the cache.</returns> bool ReadCache(FileInfo fileInfo) { Log.Source.TraceInformation("Read cache {0}", fileInfo); string path = fileInfo.FullName; var data = _Cache.Get(path); if (data == null) return false; ++_Cache.CountLoaded; bool done = false; ModuleManager manager = null; try { // read data EnumerableReader reader = new EnumerableReader((IEnumerable)data); // >> Stamp var assemblyStamp = (long)reader.Read(); if (assemblyStamp != fileInfo.LastWriteTime.Ticks) return false; // new manager, add it now, remove later on errors manager = new ModuleManager(path); _Managers.Add(manager.ModuleName, manager); // read and load data var settings = manager.ReadSettings(); manager.LoadData(settings); // >> Culture of cached resources var savedCulture = (string)reader.Read(); // check the culture if (savedCulture.Length > 0) { // the culture changed, ignore the cache if (savedCulture != manager.CurrentUICulture.Name) return false; // restore the flag manager.CachedResources = true; } // >> Settings manager.HasSettings = (bool)reader.Read(); object kind; while (null != (kind = reader.TryRead())) { ProxyAction action = null; switch ((ModuleItemKind)kind) { case ModuleItemKind.Host: { manager.SetModuleHost((string)reader.Read()); } break; case ModuleItemKind.Command: { var it = new ProxyCommand(manager, reader); Host.Instance.RegisterProxyCommand(it); action = it; } break; case ModuleItemKind.Editor: { var it = new ProxyEditor(manager, reader); Host.Instance.RegisterProxyEditor(it); action = it; } break; case ModuleItemKind.Drawer: { var it = new ProxyDrawer(manager, reader); Host.Instance.RegisterProxyDrawer(it); action = it; } break; case ModuleItemKind.Tool: { var it = new ProxyTool(manager, reader); Host.Instance.RegisterProxyTool(it); action = it; } break; default: throw new ModuleException(); } if (action != null) action.LoadData((Hashtable)settings[action.Id]); } done = true; } catch (ModuleException) { // ignore known } catch (Exception ex) { throw new ModuleException(string.Format(null, "Error on reading the cache for '{0}'.", path), ex); } finally { if (!done) { // remove cached data _Cache.Remove(path); // remove the manager if (manager != null) RemoveModuleManager(manager); } } return done; }
/// <summary> /// Reads the module from the cache. /// </summary> /// <param name="fileInfo">Module file information.</param> /// <returns>True if the module has been loaded from the cache.</returns> bool ReadCache(FileInfo fileInfo) { Log.Source.TraceInformation("Read cache {0}", fileInfo); string path = fileInfo.FullName; var data = _Cache.Get(path); if (data == null) { return(false); } ++_Cache.CountLoaded; bool done = false; ModuleManager manager = null; try { // read data EnumerableReader reader = new EnumerableReader((IEnumerable)data); // >> Stamp var assemblyStamp = (long)reader.Read(); if (assemblyStamp != fileInfo.LastWriteTime.Ticks) { return(false); } // new manager, add it now, remove later on errors manager = new ModuleManager(path); _Managers.Add(manager.ModuleName, manager); // read and load data var settings = manager.ReadSettings(); manager.LoadData(settings); // >> Culture of cached resources var savedCulture = (string)reader.Read(); // check the culture if (savedCulture.Length > 0) { // the culture changed, ignore the cache if (savedCulture != manager.CurrentUICulture.Name) { return(false); } // restore the flag manager.CachedResources = true; } // >> Settings manager.HasSettings = (bool)reader.Read(); object kind; while (null != (kind = reader.TryRead())) { ProxyAction action = null; switch ((ModuleItemKind)kind) { case ModuleItemKind.Host: { manager.SetModuleHost((string)reader.Read()); } break; case ModuleItemKind.Command: { var it = new ProxyCommand(manager, reader); Host.Instance.RegisterProxyCommand(it); action = it; } break; case ModuleItemKind.Editor: { var it = new ProxyEditor(manager, reader); Host.Instance.RegisterProxyEditor(it); action = it; } break; case ModuleItemKind.Drawer: { var it = new ProxyDrawer(manager, reader); Host.Instance.RegisterProxyDrawer(it); action = it; } break; case ModuleItemKind.Tool: { var it = new ProxyTool(manager, reader); Host.Instance.RegisterProxyTool(it); action = it; } break; default: throw new ModuleException(); } if (action != null) { action.LoadData((Hashtable)settings[action.Id]); } } done = true; } catch (ModuleException) { // ignore known } catch (Exception ex) { throw new ModuleException(string.Format(null, "Error on reading the cache for '{0}'.", path), ex); } finally { if (!done) { // remove cached data _Cache.Remove(path); // remove the manager if (manager != null) { RemoveModuleManager(manager); } } } return(done); }
/// <summary> /// Loads the module assembly. /// </summary> /// <param name="fileName">The assembly path to load a module from.</param> void LoadModule(string fileName) { Log.Source.TraceInformation("Load module {0}", fileName); // use the file info to reduce file access var fileInfo = new FileInfo(fileName); if (!fileInfo.Exists) { Log.Source.TraceInformation("Module is not found."); return; } // load from the cache if (ReadCache(fileInfo)) return; // add new module manager now, it will be removed on errors ModuleManager manager = new ModuleManager(fileInfo.FullName); _Managers.Add(manager.ModuleName, manager); // read and load data var settings = manager.ReadSettings(); manager.LoadData(settings); bool done = false; try { Log.Source.TraceInformation("Load module {0}", manager.ModuleName); int actionCount = 0; Assembly assembly = manager.LoadAssembly(); foreach (Type type in assembly.GetExportedTypes()) { if (typeof(BaseModuleItem).IsAssignableFrom(type) && !type.IsAbstract) actionCount += LoadType(manager, settings, type); else if (!manager.HasSettings && typeof(ApplicationSettingsBase).IsAssignableFrom(type) && !type.IsAbstract) manager.HasSettings = true; } // if the module has the host to load then load it now, if it is not loaded then the module should be cached if (!manager.LoadLoadableModuleHost()) { if (0 == actionCount) throw new ModuleException("A module must have a public action or a pre-loadable host."); SaveModuleCache(manager, fileInfo); } // done done = true; } finally { if (!done) RemoveModuleManager(manager); } }