public static void Initialize() { using (new WriteLockDisposable(Locker)) { using (DisposableTimer.TraceDuration<PluginManager>("Start Initialise", "End Initialise")) { var settings = RebelSettings.GetSettings(); try { LogHelper.TraceIfEnabled<PluginManager>("Codegen dir is {0}", () => HttpRuntime.CodegenDir); } catch { LogHelper.TraceIfEnabled<PluginManager>("Was going to log Codegendir but couldn't get it from HttpRuntime"); } var pluginPath = HostingEnvironment.MapPath(settings.PluginConfig.PluginsPath); _pluginFolder = new DirectoryInfo(pluginPath); _shadowCopyType = settings.PluginConfig.ShadowCopyType; //default is bin _shadowCopyFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/bin")); if (_shadowCopyType == PluginManagerShadowCopyType.OverrideDefaultFolder) { var shadowCopyPath = HostingEnvironment.MapPath(settings.PluginConfig.ShadowCopyPath); //if override is set, then use the one defined in config _shadowCopyFolder = new DirectoryInfo(shadowCopyPath); } else if (IsFullTrust() && _shadowCopyType == PluginManagerShadowCopyType.UseDynamicFolder) { //if in full trust and use dynamic folder, then set to CodeGen folder _shadowCopyFolder = new DirectoryInfo(AppDomain.CurrentDomain.DynamicDirectory); } var referencedPlugins = new List<PluginDefinition>(); var pluginFiles = Enumerable.Empty<FileInfo>(); try { //ensure folders are created Directory.CreateDirectory(_pluginFolder.FullName); if (_shadowCopyType != PluginManagerShadowCopyType.UseDynamicFolder) Directory.CreateDirectory(_shadowCopyFolder.FullName); Directory.CreateDirectory(Path.Combine(_pluginFolder.FullName, PackagesFolderName)); using (DisposableTimer.TraceDuration<PluginManager>("Finding plugin DLLs", "Finding plugin DLLs completed")) { //get list of all DLLs in plugins (not in bin!) //this will match the plugin folder pattern pluginFiles = _pluginFolder.GetFiles("*.dll", SearchOption.AllDirectories) .ToArray() // -> this magically reduces the time by about 100ms .Where(x => x.Directory.Parent != null && (IsPackageLibFolder(x.Directory))) .ToList(); } } catch (Exception ex) { var fail = new ApplicationException("Could not initialise plugin folder", ex); LogHelper.Error<PluginManager>(fail.Message, fail); //throw fail; } try { //Detect if there are any changes to plugins and perform any cleanup if in full trust using the dynamic folder if (DetectAndCleanStalePlugins(pluginFiles, _shadowCopyFolder)) { //if plugins changes have been detected, then shadow copy and re-save the cache files LogHelper.TraceIfEnabled<PluginManager>("Shadow copying assemblies"); //shadow copy files referencedPlugins .AddRange(pluginFiles.Select(plug => new PluginDefinition(plug, GetPackageFolderFromPluginDll(plug), PerformFileDeployAndRegistration(plug, true), plug.Directory.Parent.Name == "Core"))); //save our plugin hash value WriteCachePluginsHash(pluginFiles); //save our plugins list WriteCachePluginsList(pluginFiles); var codeBase = typeof(PluginManager).Assembly.CodeBase; var uri = new Uri(codeBase); var path = uri.LocalPath; var binFolder = Path.GetDirectoryName(path); if (_shadowCopyFolder.FullName.InvariantEquals(binFolder)) { LogHelper.Warn<PluginManager>("Performance: An app-pool recycle is likely to occur shortly because plugin changes were detected and shadow-copied to the bin folder"); } } else { LogHelper.TraceIfEnabled<PluginManager>("No plugin changes detected"); referencedPlugins .AddRange(pluginFiles.Select(plug => new PluginDefinition(plug, GetPackageFolderFromPluginDll(plug), PerformFileDeployAndRegistration(plug, false), plug.Directory.Parent.Name == "Core"))); } } catch(UnauthorizedAccessException) { //throw the exception if its UnauthorizedAccessException as this will //be because we cannot copy to the shadow copy folder, or update the rebel plugin hash/list files. throw; } catch (Exception ex) { var fail = new ApplicationException("Could not initialise plugin folder", ex); LogHelper.Error<PluginManager>(fail.Message, fail); //throw fail; } ReferencedPlugins = referencedPlugins; } } }
public static void Initialize() { using (new WriteLockDisposable(Locker)) { using (DisposableTimer.TraceDuration <PluginManager>("Start Initialise", "End Initialise")) { var settings = RebelSettings.GetSettings(); try { LogHelper.TraceIfEnabled <PluginManager>("Codegen dir is {0}", () => HttpRuntime.CodegenDir); } catch { LogHelper.TraceIfEnabled <PluginManager>("Was going to log Codegendir but couldn't get it from HttpRuntime"); } var pluginPath = HostingEnvironment.MapPath(settings.PluginConfig.PluginsPath); _pluginFolder = new DirectoryInfo(pluginPath); _shadowCopyType = settings.PluginConfig.ShadowCopyType; //default is bin _shadowCopyFolder = new DirectoryInfo(HostingEnvironment.MapPath("~/bin")); if (_shadowCopyType == PluginManagerShadowCopyType.OverrideDefaultFolder) { var shadowCopyPath = HostingEnvironment.MapPath(settings.PluginConfig.ShadowCopyPath); //if override is set, then use the one defined in config _shadowCopyFolder = new DirectoryInfo(shadowCopyPath); } else if (IsFullTrust() && _shadowCopyType == PluginManagerShadowCopyType.UseDynamicFolder) { //if in full trust and use dynamic folder, then set to CodeGen folder _shadowCopyFolder = new DirectoryInfo(AppDomain.CurrentDomain.DynamicDirectory); } var referencedPlugins = new List <PluginDefinition>(); var pluginFiles = Enumerable.Empty <FileInfo>(); try { //ensure folders are created Directory.CreateDirectory(_pluginFolder.FullName); if (_shadowCopyType != PluginManagerShadowCopyType.UseDynamicFolder) { Directory.CreateDirectory(_shadowCopyFolder.FullName); } Directory.CreateDirectory(Path.Combine(_pluginFolder.FullName, PackagesFolderName)); using (DisposableTimer.TraceDuration <PluginManager>("Finding plugin DLLs", "Finding plugin DLLs completed")) { //get list of all DLLs in plugins (not in bin!) //this will match the plugin folder pattern pluginFiles = _pluginFolder.GetFiles("*.dll", SearchOption.AllDirectories) .ToArray() // -> this magically reduces the time by about 100ms .Where(x => x.Directory.Parent != null && (IsPackageLibFolder(x.Directory))) .ToList(); } } catch (Exception ex) { var fail = new ApplicationException("Could not initialise plugin folder", ex); LogHelper.Error <PluginManager>(fail.Message, fail); //throw fail; } try { //Detect if there are any changes to plugins and perform any cleanup if in full trust using the dynamic folder if (DetectAndCleanStalePlugins(pluginFiles, _shadowCopyFolder)) { //if plugins changes have been detected, then shadow copy and re-save the cache files LogHelper.TraceIfEnabled <PluginManager>("Shadow copying assemblies"); //shadow copy files referencedPlugins .AddRange(pluginFiles.Select(plug => new PluginDefinition(plug, GetPackageFolderFromPluginDll(plug), PerformFileDeployAndRegistration(plug, true), plug.Directory.Parent.Name == "Core"))); //save our plugin hash value WriteCachePluginsHash(pluginFiles); //save our plugins list WriteCachePluginsList(pluginFiles); var codeBase = typeof(PluginManager).Assembly.CodeBase; var uri = new Uri(codeBase); var path = uri.LocalPath; var binFolder = Path.GetDirectoryName(path); if (_shadowCopyFolder.FullName.InvariantEquals(binFolder)) { LogHelper.Warn <PluginManager>("Performance: An app-pool recycle is likely to occur shortly because plugin changes were detected and shadow-copied to the bin folder"); } } else { LogHelper.TraceIfEnabled <PluginManager>("No plugin changes detected"); referencedPlugins .AddRange(pluginFiles.Select(plug => new PluginDefinition(plug, GetPackageFolderFromPluginDll(plug), PerformFileDeployAndRegistration(plug, false), plug.Directory.Parent.Name == "Core"))); } } catch (UnauthorizedAccessException) { //throw the exception if its UnauthorizedAccessException as this will //be because we cannot copy to the shadow copy folder, or update the rebel plugin hash/list files. throw; } catch (Exception ex) { var fail = new ApplicationException("Could not initialise plugin folder", ex); LogHelper.Error <PluginManager>(fail.Message, fail); //throw fail; } ReferencedPlugins = referencedPlugins; } } }