Пример #1
0
        private void NotifyUserThatARestartIsRequired(RestartReason reason)
        {
            if (restartReasonsTheUserHasAlreadyBeenNotifiedAbout.Contains(reason))
            {
                return;
            }

            string reasonText;

            switch (reason)
            {
            case RestartReason.ReferencedAssemblyEdited:
                reasonText =
                    "Referenced Assemblies cannot be reloaded from different paths without a restart. ";
                break;

            case RestartReason.NewAssemblyCannotBeLoadedDueToNameConflict:
                reasonText =
                    "An Assembly has already been loaded with that name (not filename, actual Assembly name) from a different path.";
                break;

            default:
                throw new ArgumentOutOfRangeException("reason");
            }

            reasonText += "Any changes you make will not take " +
                          "effect until you save and restart the application. You may continue to make changes, " +
                          "just remember to save your project and restart ArchAngel when you are done";

            MessageBox.Show(this, reasonText, "Application Restart Required");
            restartReasonsTheUserHasAlreadyBeenNotifiedAbout.Add(reason);
        }
Пример #2
0
        private static void AttachModulesWatcher(string moduleFolder, bool includeSubdirectories, IHostApplicationLifetime applicationLifetime, Action <bool> restart)
        {
            if (!Directory.Exists(moduleFolder))
            {
                //Do nothing for none existant folders
                return;
            }
            FileSystemWatcher fileWatcher;
            RestartReason     restartReason = new RestartReason();

            fileWatcher = new FileSystemWatcher(moduleFolder)
            {
                // watch for everything
                NotifyFilter          = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName,
                IncludeSubdirectories = includeSubdirectories,
                Filter = "*.*"
            };
            // Add event handlers.
            fileWatcher.Changed += OnChanged;
            fileWatcher.Created += OnChanged;
            fileWatcher.Deleted += OnChanged;
            fileWatcher.Renamed += OnRenamed;

            // Begin watching...
            fileWatcher.EnableRaisingEvents = true;


            void OnChanged(object source, FileSystemEventArgs e)
            {
                fileWatcher.EnableRaisingEvents = false;
                //Bug in Docker which will trigger OnChanged during StartUp (How to fix?)
                AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                restartReason.Reason      = "File Changed";
                restartReason.Description = $"ChangeType: {e.ChangeType} file {e.FullPath}";
                RestartApplication(applicationLifetime, restartReason, restart);
            }

            void OnRenamed(object source, RenamedEventArgs e)
            {
                fileWatcher.EnableRaisingEvents             = false;
                AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                restartReason.Reason      = "File Renamed";
                restartReason.Description = $"Renaming from {e.OldFullPath} to {e.FullPath}";
                RestartApplication(applicationLifetime, restartReason, restart);
            }
        }
Пример #3
0
        public static RestartReason CheckForUpdates(string identifier, string updateUrl)
        {
            // Don't check for updates on non-DEPLOY builds; the URLs don't work and it seems
            // undesirable anyway.
#if DEPLOY
            IVsExtensionManager extensionManager   = Package.GetGlobalService(typeof(SVsExtensionManager)) as IVsExtensionManager;
            IInstalledExtension installedExtension = extensionManager.GetInstalledExtension(identifier);
            if (installedExtension == null)
            {
                throw new Exception(String.Format("Unable to find extension: {0}", identifier));
            }

            RepositoryEntry entry = new RepositoryEntry();
            entry.DownloadUrl = updateUrl;

            IVsExtensionRepository repository      = Package.GetGlobalService(typeof(SVsExtensionRepository)) as IVsExtensionRepository;
            IInstallableExtension  latestExtension = repository.Download(entry);

            if (latestExtension.Header.Version > installedExtension.Header.Version)
            {
                RestartReason reason = RestartReason.None;
                reason |= extensionManager.Disable(installedExtension);
                extensionManager.Uninstall(installedExtension);

                try {
                    reason |= extensionManager.Install(latestExtension, /*perMachine*/ false);

                    // Enable the new one.
                    IInstalledExtension latestInstalledExtension = extensionManager.GetInstalledExtension(latestExtension.Header.Identifier);
                    reason |= extensionManager.Enable(latestInstalledExtension);
                    return(reason);
                } catch {
                    // Revert the uninstallation.
                    extensionManager.RevertUninstall(installedExtension);
                    extensionManager.Enable(installedExtension);
                    throw;
                }
            }
#endif
            return(RestartReason.None);
        }
        private void TryInstallVsIntegration([CanBeNull] IVsExtensionManager vsExtensionManager)
        {
            if (vsExtensionManager == null)
            {
                return;
            }

            IInstalledExtension vsIntegrationExtension;

            if (vsExtensionManager.TryGetInstalledExtension(VsIntegrationExtensionId, out vsIntegrationExtension))
            {
                return;
            }

            FileSystemPath thisAssemblyPath = FileSystemPath.TryParse(typeof(VsIntegrationInstaller).Assembly.Location);

            if (thisAssemblyPath.IsNullOrEmpty())
            {
                return;
            }

            FileSystemPath vsixPath = thisAssemblyPath.Directory.Combine(VsIntegrationExtensionId + ".vsix");

            if (!vsixPath.ExistsFile)
            {
                MessageBox.ShowInfo("Does not exist: \"{0}\"".FormatEx(vsixPath.FullPath));
                return;
            }

            IInstallableExtension installableExtension = vsExtensionManager.CreateInstallableExtension(vsixPath.FullPath);
            RestartReason         restartReason        = vsExtensionManager.Install(installableExtension, false);

            if (restartReason != RestartReason.None)
            {
                _restartRequired = true;
            }
        }
Пример #5
0
 public static void RestartApplication(IHostApplicationLifetime applicationLifetime, RestartReason restartReason, Action <bool> restart = null)
 {
     try
     {
         if (applicationLifetime != null)
         {
             if (restartReason != null)
             {
                 KraftLogger.LogDebug($"Method: RestartApplication: Stopping application Reason: {restartReason.Reason} additional info {restartReason.Description}");
             }
             applicationLifetime.StopApplication();
             if (!applicationLifetime.ApplicationStopping.IsCancellationRequested)
             {
                 Task.Delay(10 * 1000, applicationLifetime.ApplicationStopping);
             }
             restart?.Invoke(true);
         }
         else
         {
             KraftLogger.LogDebug("Method: RestartApplication: applicationLifetime is null.");
         }
     }
     catch (Exception exception)
     {
         KraftLogger.LogError(exception, "Method: RestartApplication(IApplicationLifetime applicationLifetime)");
     }
 }
        public static IApplicationBuilder UseBindKraft(this IApplicationBuilder app, IHostingEnvironment env)
        {
            //AntiforgeryService
            //app.Use(next => context =>
            //{
            //    if (string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase))
            //    {
            //        AntiforgeryTokenSet tokens = app.ApplicationServices.GetService<IAntiforgery>().GetAndStoreTokens(context);
            //        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
            //    }
            //    return next(context);
            //});

            _KraftGlobalConfigurationSettings.EnvironmentSettings = new KraftEnvironmentSettings(env.ApplicationName, env.ContentRootPath, env.EnvironmentName, env.WebRootPath);
            try
            {
                ILoggerFactory     loggerFactory      = app.ApplicationServices.GetService <ILoggerFactory>();
                DiagnosticListener diagnosticListener = app.ApplicationServices.GetService <DiagnosticListener>();
                //First statement to register Error handling !!!Keep at the top!!!
                app.UseMiddleware <KraftExceptionHandlerMiddleware>(loggerFactory, new ExceptionHandlerOptions(), diagnosticListener);
                AppDomain.CurrentDomain.UnhandledException += AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    += AppDomain_OnAssemblyResolve;
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToWww)
                {
                    RewriteOptions rewrite = new RewriteOptions();
                    rewrite.AddRedirectToWwwPermanent();
                    app.UseRewriter(rewrite);
                }
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToHttps)
                {
                    app.UseForwardedHeaders();
                    app.UseHsts();
                    app.UseHttpsRedirection();
                }
                ExtensionMethods.Init(app, _Logger);
                app.UseBindKraftLogger(env, loggerFactory, ERRORURLSEGMENT);
                app.UseBindKraftProfiler(env, loggerFactory, _MemoryCache);
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }

                _Builder = app;

                BundleCollection bundleCollection = app.UseBundling(env, loggerFactory.CreateLogger("Bundling"), _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlCssJsSegment, _KraftGlobalConfigurationSettings.GeneralSettings.EnableOptimization);
                bundleCollection.EnableInstrumentations = env.IsDevelopment(); //Logging enabled

                #region Initial module registration
                foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
                {
                    if (!Directory.Exists(dir))
                    {
                        throw new Exception($"No \"{dir}\" directory found! The CoreKraft initialization cannot continue.");
                    }
                }
                string kraftUrlSegment = _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlSegment;

                try
                {
                    KraftModuleCollection       modulesCollection   = app.ApplicationServices.GetService <KraftModuleCollection>();
                    Dictionary <string, string> moduleKey2Path      = new Dictionary <string, string>();
                    IApplicationLifetime        applicationLifetime = app.ApplicationServices.GetRequiredService <IApplicationLifetime>();
                    lock (_SyncRoot)
                    {
                        foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
                        {
                            string[] moduleDirectories = Directory.GetDirectories(dir);
                            foreach (string subdirectory in moduleDirectories)
                            {
                                DirectoryInfo moduleDirectory = new DirectoryInfo(subdirectory);
                                if (moduleDirectory.Name != null && moduleDirectory.Name.Equals("_PluginsReferences", StringComparison.InvariantCultureIgnoreCase))
                                {
                                    continue;
                                }
                                ICachingService cachingService = app.ApplicationServices.GetService <ICachingService>();
                                KraftModule     kraftModule    = modulesCollection.GetModule(moduleDirectory.Name);
                                if (kraftModule != null)
                                {
                                    continue;
                                }
                                kraftModule = modulesCollection.RegisterModule(dir, moduleDirectory.Name, cachingService);
                                if (kraftModule == null || !kraftModule.IsInitialized)
                                {
                                    _Logger.LogInformation($"Module not created for directory \"{moduleDirectory.Name}\" because of missing configuration files.");
                                    continue;
                                }
                                KraftStaticFiles.RegisterStaticFiles(app, moduleDirectory.FullName, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModuleImages);
                                KraftStaticFiles.RegisterStaticFiles(app, moduleDirectory.FullName, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModulePublic);
                                moduleKey2Path.Add(kraftModule.Key.ToLower(), dir);
                                //The application will restart when some files changed in the modules directory and subdirectories but only in RELEASE
                                //Check if module is initialized Robert
                                if (kraftModule.IsInitialized && !env.IsDevelopment())
                                {
                                    string moduleFullPath = Path.Combine(dir, kraftModule.Key);
                                    AttachModulesWatcher(moduleFullPath, false, applicationLifetime);
                                    string path2Data = Path.Combine(moduleFullPath, "Data");
                                    if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                                    {
                                        throw new SecurityException($"Write access to folder {path2Data} is required!");
                                    }
                                    path2Data = Path.Combine(moduleFullPath, "Images");
                                    if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                                    {
                                        throw new SecurityException($"Write access to folder {path2Data} is required!");
                                    }
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Css"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Documentation"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Localization"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "NodeSets"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Scripts"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Templates"), true, applicationLifetime);
                                    AttachModulesWatcher(Path.Combine(moduleFullPath, "Views"), true, applicationLifetime);
                                }
                            }
                        }
                        //try to construct all modules
                        modulesCollection.ResolveModuleDependencies();
                        _KraftGlobalConfigurationSettings.GeneralSettings.ModuleKey2Path = moduleKey2Path;
                    }
                    if (!env.IsDevelopment())
                    {
                        _Configuration.GetReloadToken().RegisterChangeCallback(_ =>
                        {
                            RestartReason restartReason = new RestartReason();
                            restartReason.Reason        = "Configuration Changed";
                            restartReason.Description   = $"'appsettings.Production.json' has been altered";
                            AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                            AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                            RestartApplication(applicationLifetime, restartReason);
                        }, null);
                    }
                }
                catch (Exception boom)
                {
                    KraftLogger.LogError(boom);
                    throw new Exception($"CoreKrafts module construction failed! {boom.Message}");
                }
                #endregion Initial module registration
                //Configure the CoreKraft routing
                RouteHandler kraftRoutesHandler = new RouteHandler(KraftMiddleware.ExecutionDelegate(app, _KraftGlobalConfigurationSettings));
                app.UseRouter(KraftRouteBuilder.MakeRouter(app, kraftRoutesHandler, kraftUrlSegment));
                app.UseSession();
                if (_KraftGlobalConfigurationSettings.GeneralSettings.AuthorizationSection.RequireAuthorization)
                {
                    app.UseAuthentication();
                }
                //KraftKeepAlive.RegisterKeepAliveAsync(builder);
                //Configure eventually SignalR
                try
                {
                    if (_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.UseSignalR)
                    {
                        app.UseSignalR(routes =>
                        {
                            MethodInfo mapHub  = typeof(HubRouteBuilder).GetMethod("MapHub", new[] { typeof(PathString) });
                            MethodInfo generic = mapHub.MakeGenericMethod(Type.GetType(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubImplementationAsString));
                            generic.Invoke(routes, new object[] { new PathString(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubRoute) });
                        });
                    }
                }
                catch (Exception e)
                {
                    KraftLogger.LogError("Register signalR middleware. Exception: " + e);
                }
                //Signals
                SignalStartup signalStartup = new SignalStartup(app.ApplicationServices, _KraftGlobalConfigurationSettings);
                signalStartup.ExecuteSignalsOnStartup();
                //End Signals
            }
            catch (Exception ex)
            {
                KraftLogger.LogError("Method: UseBindKraft ", ex);
                KraftExceptionHandlerMiddleware.Exceptions[KraftExceptionHandlerMiddleware.EXCEPTIONSONCONFIGURE].Add(ex);
            }

            //This is the last statement
            KraftExceptionHandlerMiddleware.HandleErrorAction(app);
            return(app);
        }
Пример #7
0
 public void AddResult(ExtensionEntry extension, RestartReason result)
 {
     _results.Add(new AResult(extension, result));
 }
Пример #8
0
 public AResult(ExtensionEntry extension, RestartReason result)
 {
     this.Extension = extension;
     this.Result    = result;
 }
Пример #9
0
        private void NotifyUserThatARestartIsRequired(RestartReason reason)
        {
            if (restartReasonsTheUserHasAlreadyBeenNotifiedAbout.Contains(reason)) return;

            string reasonText;

            switch (reason)
            {
                case RestartReason.ReferencedAssemblyEdited:
                    reasonText =
                        "Referenced Assemblies cannot be reloaded from different paths without a restart. ";
                    break;
                case RestartReason.NewAssemblyCannotBeLoadedDueToNameConflict:
                    reasonText =
                        "An Assembly has already been loaded with that name (not filename, actual Assembly name) from a different path.";
                    break;
                default:
                    throw new ArgumentOutOfRangeException("reason");
            }

            reasonText += "Any changes you make will not take " +
                        "effect until you save and restart the application. You may continue to make changes, " +
                        "just remember to save your project and restart ArchAngel when you are done";

            MessageBox.Show(this, reasonText, "Application Restart Required");
            restartReasonsTheUserHasAlreadyBeenNotifiedAbout.Add(reason);
        }
        private static void AttachModulesWatcher(string moduleFolder, bool includeSubdirectories, IApplicationLifetime applicationLifetime)
        {
            if (!Directory.Exists(moduleFolder))
            {
                //Do nothing for none existant folders
                return;
            }
            FileSystemWatcher fileWatcher;
            RestartReason     restartReason = new RestartReason();

            if (includeSubdirectories)
            {
                fileWatcher = new FileSystemWatcher(moduleFolder);
                // watch for everything
                fileWatcher.NotifyFilter          = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                fileWatcher.IncludeSubdirectories = includeSubdirectories;
                fileWatcher.Filter = "*.*";
                // Add event handlers.
                fileWatcher.Changed += new FileSystemEventHandler(OnChanged);
                fileWatcher.Created += new FileSystemEventHandler(OnChanged);
                fileWatcher.Deleted += new FileSystemEventHandler(OnChanged);
                fileWatcher.Renamed += new RenamedEventHandler(OnRenamed);

                // Begin watching...
                fileWatcher.EnableRaisingEvents = true;
            }
            else //only for the files
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(moduleFolder);
                foreach (FileInfo file in directoryInfo.GetFiles())
                {
                    fileWatcher              = new FileSystemWatcher();
                    fileWatcher.Path         = directoryInfo.FullName;
                    fileWatcher.Filter       = file.Name;
                    fileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName;
                    // Add event handlers.
                    fileWatcher.Changed += new FileSystemEventHandler(OnChanged);
                    fileWatcher.Created += new FileSystemEventHandler(OnChanged);
                    fileWatcher.Deleted += new FileSystemEventHandler(OnChanged);
                    fileWatcher.Renamed += new RenamedEventHandler(OnRenamed);
                    // Begin watching...
                    fileWatcher.EnableRaisingEvents = true;
                }
            }

            void OnChanged(object source, FileSystemEventArgs e)
            {
                //Bug in Docker which will trigger OnChanged during StartUp (How to fix?)
                AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                restartReason.Reason      = "File Changed";
                restartReason.Description = $"ChangeType: {e.ChangeType} file {e.FullPath}";
                RestartApplication(applicationLifetime, restartReason);
            }

            void OnRenamed(object source, RenamedEventArgs e)
            {
                AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                restartReason.Reason      = "File Renamed";
                restartReason.Description = $"Renaming from {e.OldFullPath} to {e.FullPath}";
                RestartApplication(applicationLifetime, restartReason);
            }
        }
Пример #11
0
        public static IApplicationBuilder UseBindKraft(this IApplicationBuilder app, IWebHostEnvironment env, Action <bool> restart = null)
        {
            //AntiforgeryService
            //app.Use(next => context =>
            //{
            //    if (string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase))
            //    {
            //        AntiforgeryTokenSet tokens = app.ApplicationServices.GetService<IAntiforgery>().GetAndStoreTokens(context);
            //        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
            //    }
            //    return next(context);
            //});

            _KraftGlobalConfigurationSettings.EnvironmentSettings = new KraftEnvironmentSettings(env.ApplicationName, env.ContentRootPath, env.EnvironmentName, env.WebRootPath);

            try
            {
                ILoggerFactory     loggerFactory      = app.ApplicationServices.GetService <ILoggerFactory>();
                DiagnosticListener diagnosticListener = app.ApplicationServices.GetService <DiagnosticListener>();
                //First statement to register Error handling !!!Keep at the top!!!
                app.UseMiddleware <KraftExceptionHandlerMiddleware>(loggerFactory, new ExceptionHandlerOptions(), diagnosticListener);
                AppDomain.CurrentDomain.UnhandledException += AppDomain_OnUnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve    += AppDomain_OnAssemblyResolve;
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToHttps)
                {
                    app.UseForwardedHeaders();
                    app.UseHsts();
                    app.UseHttpsRedirection();
                }
                if (_KraftGlobalConfigurationSettings.GeneralSettings.RedirectToWww)
                {
                    RewriteOptions rewrite = new RewriteOptions();
                    rewrite.AddRedirectToWwwPermanent();
                    app.UseRewriter(rewrite);
                }
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider          = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "wwwroot")),
                    ServeUnknownFileTypes = true,
                    RequestPath           = new PathString(string.Empty),
                });

                ExtensionMethods.Init(app, _Logger);
                ToolSettings tool    = KraftToolsRouteBuilder.GetTool(_KraftGlobalConfigurationSettings, "errors");
                string       segment = null;
                if (tool != null && tool.Enabled)//Errors enabled from configuration
                {
                    segment = tool.Url;
                }
                app.UseBindKraftLogger(env, loggerFactory, segment);
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }

                string           rootVirtualPath  = "/modules";
                BundleCollection bundleCollection = app.UseBundling(env,
                                                                    _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders,
                                                                    rootVirtualPath,
                                                                    loggerFactory.CreateLogger("Bundling"),
                                                                    _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlCssJsSegment,
                                                                    _KraftGlobalConfigurationSettings.GeneralSettings.EnableOptimization);
                bundleCollection.EnableInstrumentations = env.IsDevelopment(); //Logging enabled

                #region Initial module registration
                foreach (string dir in _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders)
                {
                    if (!Directory.Exists(dir))
                    {
                        throw new Exception($"No \"{dir}\" directory found in the setting ModulesRootFolders! The CoreKraft initialization cannot continue.");
                    }
                }
                string kraftUrlSegment = _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlSegment;
                try
                {
                    KraftModuleCollection    modulesCollection   = app.ApplicationServices.GetService <KraftModuleCollection>();
                    IHostApplicationLifetime applicationLifetime = app.ApplicationServices.GetRequiredService <IHostApplicationLifetime>();
                    lock (_SyncRoot)
                    {
                        KraftModulesConstruction kraftModulesConstruction = new KraftModulesConstruction();
                        Dictionary <string, IDependable <KraftDependableModule> > kraftDependableModules = kraftModulesConstruction.Init(_KraftGlobalConfigurationSettings.GeneralSettings.DefaultStartModule, _KraftGlobalConfigurationSettings.GeneralSettings.ModulesRootFolders);

                        ICachingService             cachingService = app.ApplicationServices.GetService <ICachingService>();
                        Dictionary <string, string> moduleKey2Path = new Dictionary <string, string>();
                        foreach (KeyValuePair <string, IDependable <KraftDependableModule> > depModule in kraftDependableModules)
                        {
                            KraftDependableModule kraftDependable = (depModule.Value as KraftDependableModule);
                            KraftModule           kraftModule     = modulesCollection.RegisterModule(kraftDependable.KraftModuleRootPath, depModule.Value.Key, kraftDependable, cachingService);
                            KraftStaticFiles.RegisterStaticFiles(app, kraftModule.ModulePath, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModuleImages);
                            KraftStaticFiles.RegisterStaticFiles(app, kraftModule.ModulePath, kraftUrlSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlResourceSegment, _KraftGlobalConfigurationSettings.GeneralSettings.KraftUrlModulePublic);
                            moduleKey2Path.Add(kraftModule.Key, kraftDependable.KraftModuleRootPath);
                            string moduleFullPath = Path.Combine(kraftDependable.KraftModuleRootPath, kraftModule.Key);
                            string path2Data      = Path.Combine(moduleFullPath, "Data");
                            if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                            {
                                throw new SecurityException($"Write access to folder {path2Data} is required!");
                            }
                            path2Data = Path.Combine(moduleFullPath, "Images");
                            if (!HasWritePermissionOnDir(new DirectoryInfo(path2Data), true))
                            {
                                throw new SecurityException($"Write access to folder {path2Data} is required!");
                            }
                            foreach (string validSubFolder in _ValidSubFoldersForWatching)
                            {
                                AttachModulesWatcher(Path.Combine(moduleFullPath, validSubFolder), true, applicationLifetime, restart);
                            }
                        }
                        _KraftGlobalConfigurationSettings.GeneralSettings.ModuleKey2Path = moduleKey2Path;
                    }
                    #region Watching appsettings, PassThroughJsConfig, nlogConfig
                    //appsettings.{Production} configuration watch
                    _Configuration.GetReloadToken().RegisterChangeCallback(_ =>
                    {
                        string environment = "Production";
                        if (env.IsDevelopment())
                        {
                            environment = "Development";
                        }
                        RestartReason restartReason = new RestartReason
                        {
                            Reason      = "appsettings-Configuration Changed",
                            Description = $"'appsettings.{environment}.json' has been altered"
                        };
                        AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                        AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                        RestartApplication(applicationLifetime, restartReason, restart);
                    }, null);
                    //PassThroughJsConfig configuration watch
                    IChangeToken changeTokenPassThroughJsConfig = _KraftGlobalConfigurationSettings.GeneralSettings.BindKraftConfigurationGetReloadToken(env);
                    if (changeTokenPassThroughJsConfig != null)
                    {
                        changeTokenPassThroughJsConfig.RegisterChangeCallback(_ =>
                        {
                            RestartReason restartReason = new RestartReason
                            {
                                Reason      = "PassThroughJsConfig Changed",
                                Description = $"'{_KraftGlobalConfigurationSettings.GeneralSettings.PassThroughJsConfig}' has been altered"
                            };
                            AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                            AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                            RestartApplication(applicationLifetime, restartReason, restart);
                        }, null);
                    }
                    FileInfo nlogConfig = new FileInfo(Path.Combine(env.ContentRootPath, "nlog.config"));
                    if (nlogConfig.Exists)
                    {
                        IChangeToken changeTokenNlogConfig = env.ContentRootFileProvider.Watch(nlogConfig.Name);
                        if (changeTokenNlogConfig != null)
                        {
                            changeTokenNlogConfig.RegisterChangeCallback(_ =>
                            {
                                RestartReason restartReason = new RestartReason
                                {
                                    Reason      = "Nlog.config Changed",
                                    Description = $"'Nlog.config' has been altered"
                                };
                                AppDomain.CurrentDomain.UnhandledException -= AppDomain_OnUnhandledException;
                                AppDomain.CurrentDomain.AssemblyResolve    -= AppDomain_OnAssemblyResolve;
                                RestartApplication(applicationLifetime, restartReason, restart);
                            }, null);
                        }
                    }
                    #endregion End: Watching appsettings, PassThroughJsConfig, nlogConfig
                }
                catch (Exception boom)
                {
                    KraftLogger.LogError(boom);
                    throw new Exception($"CoreKrafts module construction failed! {boom.Message}");
                }
                #endregion Initial module registration
                //Configure the CoreKraft routing
                RouteHandler kraftRoutesHandler = new RouteHandler(KraftMiddleware.ExecutionDelegate(app, _KraftGlobalConfigurationSettings));
                app.UseRouter(KraftRouteBuilder.MakeRouter(app, kraftRoutesHandler, kraftUrlSegment));

                #region Tools routing
                KraftToolsRouteBuilder.MakeRouters(app, _KraftGlobalConfigurationSettings);
                #endregion Tools routing

                DirectCallService.Instance.Call = KraftMiddleware.ExecutionDelegateDirect(app, _KraftGlobalConfigurationSettings);
                app.UseSession();
                if (_KraftGlobalConfigurationSettings.GeneralSettings.AuthorizationSection.RequireAuthorization)
                {
                    app.UseAuthentication();
                }
                //KraftKeepAlive.RegisterKeepAliveAsync(builder);
                //Configure eventually SignalR
                try
                {
                    if (_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.UseSignalR)
                    {
                        app.UseRouting();
                        app.UseEndpoints(endpoints =>
                        {
                            MethodInfo mapHub = typeof(HubEndpointRouteBuilderExtensions).GetMethod(
                                "MapHub", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(IEndpointRouteBuilder), typeof(string), typeof(Action <HttpConnectionDispatcherOptions>) }, null);
                            MethodInfo generic = mapHub.MakeGenericMethod(Type.GetType(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubImplementationAsString, true));
                            generic.Invoke(null,
                                           new object[] { endpoints, new string(_KraftGlobalConfigurationSettings.GeneralSettings.SignalRSettings.HubRoute),
                                                          (Action <HttpConnectionDispatcherOptions>)(x => { x.ApplicationMaxBufferSize = 3200000; x.WebSockets.CloseTimeout = TimeSpan.FromSeconds(30); x.LongPolling.PollTimeout = TimeSpan.FromSeconds(180); }) });
                        });
                    }
                }
                catch (Exception e)
                {
                    KraftLogger.LogError("Register signalR middleware. Exception: " + e);
                }
                //Signals
                SignalStartup signalStartup = new SignalStartup(app.ApplicationServices, _KraftGlobalConfigurationSettings);
                signalStartup.ExecuteSignalsOnStartup();
                //End Signals
            }
            catch (Exception ex)
            {
                KraftLogger.LogError("Method: UseBindKraft ", ex);
                KraftExceptionHandlerMiddleware.Exceptions[KraftExceptionHandlerMiddleware.EXCEPTIONSONCONFIGURE].Add(ex);
            }

            //This is the last statement
            KraftExceptionHandlerMiddleware.HandleErrorAction(app);
            return(app);
        }