ShellContext IShellContextFactory.CreateShellContext( ShellSettings settings) { var sw = Stopwatch.StartNew(); _logger.LogInformation("Creating shell context for tenant {0}", settings.Name); var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor()); var provider = _shellContainerFactory.CreateContainer(settings, blueprint); try { var shellcontext = new ShellContext { Settings = settings, Blueprint = blueprint, LifetimeScope = provider, Shell = provider.GetRequiredService <IOrchardShell>() }; _logger.LogVerbose("Created shell context for tenant {0} in {1}ms", settings.Name, sw.ElapsedMilliseconds); return(shellcontext); } catch (Exception ex) { _logger.LogError("Cannot create shell context", ex); throw; } }
ShellContext IShellContextFactory.CreateShellContext(ShellSettings settings) { var sw = Stopwatch.StartNew(); if (_logger.IsEnabled(LogLevel.Information)) { _logger.LogInformation("Creating shell context for tenant {0}", settings.Name); } var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor()); var provider = _shellContainerFactory.CreateContainer(settings, blueprint); try { var shellcontext = new ShellContext { Settings = settings, Blueprint = blueprint, ServiceProvider = provider }; if (_logger.IsEnabled(LogLevel.Verbose)) { _logger.LogVerbose("Created shell context for tenant {0} in {1}ms", settings.Name, sw.ElapsedMilliseconds); } return(shellcontext); } catch (Exception ex) { _logger.LogError("Cannot create shell context", ex); throw; } }
/// <summary> /// 创建一个外壳上下文工厂。 /// </summary> /// <param name="settings">外壳设置。</param> /// <returns>外壳上下文。</returns> public ShellContext CreateShellContext(ShellSettings settings) { Logger.Debug("准备为租户 {0} 创建外壳上下文", settings.Name); var knownDescriptor = _shellDescriptorCache.Fetch(settings.Name); if (knownDescriptor == null) { Logger.Information("在缓存中找不到外壳描述符信息。 以最少的组件开始。"); var features = new List <ShellFeature>(); _minimumShellDescriptorProviders.Invoke(i => i.GetFeatures(features), Logger); knownDescriptor = MinimumShellDescriptor(features); } var blueprint = _compositionStrategy.Compose(settings, knownDescriptor); var shellScope = _shellContainerFactory.CreateContainer(settings, blueprint); ShellDescriptor currentDescriptor; using (var standaloneEnvironment = shellScope.CreateWorkContextScope()) { var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>(); currentDescriptor = shellDescriptorManager.GetShellDescriptor(); } if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber) { currentDescriptor.Features = currentDescriptor.Features.Distinct(new ShellFeatureEqualityComparer()).ToArray(); Logger.Information("获得较新的外壳描述符。重新构建外壳容器。"); _shellDescriptorCache.Store(settings.Name, currentDescriptor); blueprint = _compositionStrategy.Compose(settings, currentDescriptor); shellScope.Dispose(); shellScope = _shellContainerFactory.CreateContainer(settings, blueprint); } return(new ShellContext { Settings = settings, Descriptor = currentDescriptor, Blueprint = blueprint, Container = shellScope, Shell = shellScope.Resolve <IShell>(), }); }
private void ExecuteOnTenantScope(ShellSettings settings, Action <IWorkContextScope> action) { var shellContext = _shellContextFactory.CreateShellContext(settings); using (var container = _shellContainerFactory.CreateContainer(shellContext.Settings, shellContext.Blueprint)) { using (var environment = container.CreateWorkContextScope()) { action(environment); } } }
public ShellContext CreateShellContext(ShellSettings settings) { Logger.Debug("Creating shell context for tenant {0}", settings.Name); var knownDescriptor = _shellDescriptorCache.Fetch(settings.Name); if (knownDescriptor == null) { Logger.Information("No descriptor cached. Starting with minimum components."); knownDescriptor = MinimumShellDescriptor(); } var blueprint = _compositionStrategy.Compose(settings, knownDescriptor); var shellScope = _shellContainerFactory.CreateContainer(settings, blueprint); ShellDescriptor currentDescriptor; using (var standaloneEnvironment = shellScope.CreateWorkContextScope()) { var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>(); currentDescriptor = shellDescriptorManager.GetShellDescriptor(); } if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber) { Logger.Information("Newer descriptor obtained. Rebuilding shell container."); _shellDescriptorCache.Store(settings.Name, currentDescriptor); blueprint = _compositionStrategy.Compose(settings, currentDescriptor); shellScope.Dispose(); shellScope = _shellContainerFactory.CreateContainer(settings, blueprint); } return(new ShellContext { Settings = settings, Descriptor = currentDescriptor, Blueprint = blueprint, LifetimeScope = shellScope, Shell = shellScope.Resolve <IBoyingShell>(), }); }
ShellContext IShellContextFactory.CreateShellContext( ShellSettings settings) { _logger.LogInformation("Creating shell context for tenant {0}", settings.Name); var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor()); var provider = _shellContainerFactory.CreateContainer(settings, blueprint); try { return(new ShellContext { Settings = settings, Blueprint = blueprint, LifetimeScope = provider, Shell = provider.GetRequiredService <IOrchardShell>() }); } catch (Exception ex) { _logger.LogError("Cannot create shell context", ex); throw; } }
public ShellContext CreateDescribedContext(IShellSettings settings, IShellDescriptor descriptor) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Creating described context for tenant {0}", settings.Name); } var blueprint = _compositionStrategy.ComposeAsync(settings, descriptor).Result; var serviceProvider = _shellContainerFactory.CreateContainer(settings, blueprint); return(new ShellContext { Settings = settings, Blueprint = blueprint, ServiceProvider = serviceProvider }); }
public async Task <ShellContext> CreateDescribedContextAsync(ShellSettings settings, ShellDescriptor shellDescriptor) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Creating described context for tenant '{TenantName}'", settings.Name); } var blueprint = await _compositionStrategy.ComposeAsync(settings, shellDescriptor); var provider = _shellContainerFactory.CreateContainer(settings, blueprint); return(new ShellContext { Settings = settings, Blueprint = blueprint, ServiceProvider = provider }); }
ShellContext IShellContextFactory.CreateShellContext( ShellSettings settings) { Console.WriteLine("Creating shell context for tenant {0}", settings.Name); var blueprint = _compositionStrategy.Compose(settings, MinimumShellDescriptor()); var provider = _shellContainerFactory.CreateContainer(settings, blueprint); try { return(new ShellContext { Settings = settings, Blueprint = blueprint, LifetimeScope = provider, Shell = provider.GetService <IOrchardShell>() }); } catch (Exception ex) { Logger.Error(ex.ToString()); throw; } }
public string Setup(SetupContext context) { string executionId; Logger.Information("Running setup for tenant '{0}'.", _shellSettings.Name); // The vanilla Orchard distibution has the following features enabled. string[] hardcoded = { // Framework "Orchard.Framework", // Core "Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation", "Scheduling", "Settings", "Shapes", "Title", // Modules "Orchard.Pages", "Orchard.ContentPicker", "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules", "PackagingServices","Orchard.Packaging", "Gallery", "Orchard.Recipes" }; context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList(); var shellSettings = new ShellSettings(_shellSettings); if (String.IsNullOrEmpty(shellSettings.DataProvider)) { shellSettings.DataProvider = context.DatabaseProvider; shellSettings.DataConnectionString = context.DatabaseConnectionString; shellSettings.DataTablePrefix = context.DatabaseTablePrefix; } shellSettings.EncryptionAlgorithm = "AES"; shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString(); shellSettings.HashAlgorithm = "HMACSHA256"; shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString(); var shellDescriptor = new ShellDescriptor { Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name }) }; var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor); // Initialize database explicitly, and store shell descriptor. using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) { using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) { // Workaround to avoid a Transaction issue with PostgreSQL. environment.Resolve <ITransactionManager>().RequireNew(); var schemaBuilder = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>()); schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table .Column <int>("Id", column => column.PrimaryKey().Identity()) .Column <string>("DataMigrationClass") .Column <int>("Version")); schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord", table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version")); var dataMigrationManager = environment.Resolve <IDataMigrationManager>(); dataMigrationManager.Update("Settings"); foreach (var feature in context.EnabledFeatures) { dataMigrationManager.Update(feature); } var descriptorManager = environment.Resolve <IShellDescriptorManager>(); descriptorManager.UpdateShellDescriptor(0, shellDescriptor.Features, shellDescriptor.Parameters); } } // In effect "pump messages" see PostMessage circa 1980. while (_processingEngine.AreTasksPending()) { _processingEngine.ExecuteNextTask(); } // Create a standalone environment. // Must mark state as Running - otherwise standalone environment is created "for setup". shellSettings.State = TenantState.Running; using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) { try { executionId = CreateTenantData(context, environment); } catch { environment.Resolve <ITransactionManager>().Cancel(); throw; } } _shellSettingsManager.SaveSettings(shellSettings); return(executionId); }
public string Setup(SetupContext context) { string executionId; // The vanilla Orchard distibution has the following features enabled. string[] hardcoded = { // Framework "Orchard.Framework", // Core "Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation", "Reports", "Scheduling", "Settings", "Shapes", "Title", // Modules "Orchard.Pages", "Orchard.ContentPicker", "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules", "PackagingServices","Orchard.Packaging", "Gallery", "Orchard.Recipes" }; context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList(); var shellSettings = new ShellSettings(_shellSettings); if (string.IsNullOrEmpty(shellSettings.DataProvider)) { shellSettings.DataProvider = context.DatabaseProvider; shellSettings.DataConnectionString = context.DatabaseConnectionString; shellSettings.DataTablePrefix = context.DatabaseTablePrefix; } #region Encryption Settings shellSettings.EncryptionAlgorithm = "AES"; // randomly generated key shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString(); shellSettings.HashAlgorithm = "HMACSHA256"; // randomly generated key shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString(); #endregion var shellDescriptor = new ShellDescriptor { Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name }) }; var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor); // initialize database explicitly, and store shell descriptor using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) { using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) { // check if the database is already created (in case an exception occured in the second phase) var schemaBuilder = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>()); try { var tablePrefix = String.IsNullOrEmpty(shellSettings.DataTablePrefix) ? "" : shellSettings.DataTablePrefix + "_"; schemaBuilder.ExecuteSql("SELECT * FROM " + tablePrefix + "Settings_ShellDescriptorRecord"); } catch { var reportsCoordinator = environment.Resolve <IReportsCoordinator>(); reportsCoordinator.Register("Data Migration", "Setup", "Orchard installation"); schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table .Column <int>("Id", column => column.PrimaryKey().Identity()) .Column <string>("DataMigrationClass") .Column <int>("Version")); var dataMigrationManager = environment.Resolve <IDataMigrationManager>(); dataMigrationManager.Update("Settings"); foreach (var feature in context.EnabledFeatures) { dataMigrationManager.Update(feature); } environment.Resolve <IShellDescriptorManager>().UpdateShellDescriptor( 0, shellDescriptor.Features, shellDescriptor.Parameters); } } } // in effect "pump messages" see PostMessage circa 1980 while (_processingEngine.AreTasksPending()) { _processingEngine.ExecuteNextTask(); } // creating a standalone environment. // in theory this environment can be used to resolve any normal components by interface, and those // components will exist entirely in isolation - no crossover between the safemode container currently in effect // must mark state as Running - otherwise standalone enviro is created "for setup" shellSettings.State = TenantState.Running; using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) { try { executionId = CreateTenantData(context, environment); } catch { environment.Resolve <ITransactionManager>().Cancel(); throw; } } _shellSettingsManager.SaveSettings(shellSettings); return(executionId); }
public ShellContext CreateShellContext(ShellSettings settings) { Logger.DebugFormat("Creating shell context for tenant {0}", settings.Name); var knownDescriptor = shellDescriptorCache.Fetch(settings.Name); if (knownDescriptor == null) { Logger.Info("No descriptor cached. Starting with minimum components."); var multiTenancy = Convert.ToBoolean(ConfigurationManager.AppSettings["CMS.MultiTenancy"]); knownDescriptor = MinimumShellDescriptor(multiTenancy); } if (!string.IsNullOrEmpty(settings.DataProvider)) { var provider = CMSConfigurationSection.Instance.Data.Providers[settings.DataProvider]; if (provider != null) { if (knownDescriptor.Features.All(x => x.Name != provider.Feature)) { knownDescriptor.Features.Insert(1, new ShellFeature { Name = provider.Feature }); } } } var blueprint = compositionStrategy.Compose(settings, knownDescriptor); var shellScope = shellContainerFactory.CreateContainer(settings, blueprint); ShellDescriptor currentDescriptor; using (var standaloneEnvironment = shellScope.CreateWorkContextScope()) { var shellDescriptorManager = standaloneEnvironment.Resolve <IShellDescriptorManager>(); currentDescriptor = shellDescriptorManager.GetShellDescriptor(); if (currentDescriptor == null) { shellDescriptorManager.UpdateShellDescriptor(0, knownDescriptor.Features, false); } else { // Detect new auto activated features if (knownDescriptor.SerialNumber == currentDescriptor.SerialNumber) { var features = new List <ShellFeature>(currentDescriptor.Features); var hasNew = false; foreach (var feature in knownDescriptor.Features) { if (features.All(x => x.Name != feature.Name)) { features.Add(feature); hasNew = true; } } if (hasNew) { currentDescriptor.Features = features; shellDescriptorManager.UpdateShellDescriptor(currentDescriptor.SerialNumber, features, false); } } } } if (currentDescriptor != null && knownDescriptor.SerialNumber != currentDescriptor.SerialNumber) { Logger.Info("Newer descriptor obtained. Rebuilding shell container."); shellDescriptorCache.Store(settings.Name, currentDescriptor); blueprint = compositionStrategy.Compose(settings, currentDescriptor); shellScope.Dispose(); shellScope = shellContainerFactory.CreateContainer(settings, blueprint); } if (currentDescriptor == null) { currentDescriptor = knownDescriptor; } return(new ShellContext { Settings = settings, Descriptor = currentDescriptor, Blueprint = blueprint, LifetimeScope = shellScope, Shell = shellScope.Resolve <ICMSShell>(), }); }
private string SetupInternal(SetupContext context) { string executionId; Logger.Information("Running setup for tenant '{0}'.", _shellSettings.Name); // The vanilla Orchard distibution has the following features enabled. string[] hardcoded = { // Framework "Orchard.Framework", // Core "Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation", "Scheduling", "Settings", "Shapes", "Title", // Modules "Orchard.Pages", "Orchard.ContentPicker", "Orchard.Themes", "Orchard.Users", "Orchard.Roles", "Orchard.Modules", "PackagingServices","Orchard.Packaging", "Gallery", "Orchard.Recipes" }; context.EnabledFeatures = hardcoded.Union(context.EnabledFeatures ?? Enumerable.Empty <string>()).Distinct().ToList(); // Set shell state to "Initializing" so that subsequent HTTP requests are responded to with "Service Unavailable" while Orchard is setting up. _shellSettings.State = TenantState.Initializing; var shellSettings = new ShellSettings(_shellSettings); if (String.IsNullOrEmpty(shellSettings.DataProvider)) { shellSettings.DataProvider = context.DatabaseProvider; shellSettings.DataConnectionString = context.DatabaseConnectionString; shellSettings.DataTablePrefix = context.DatabaseTablePrefix; } shellSettings.EncryptionAlgorithm = "AES"; // Randomly generated key. shellSettings.EncryptionKey = SymmetricAlgorithm.Create(shellSettings.EncryptionAlgorithm).Key.ToHexString(); shellSettings.HashAlgorithm = "HMACSHA256"; // Randomly generated key. shellSettings.HashKey = HMAC.Create(shellSettings.HashAlgorithm).Key.ToHexString(); var shellDescriptor = new ShellDescriptor { Features = context.EnabledFeatures.Select(name => new ShellFeature { Name = name }) }; var shellBlueprint = _compositionStrategy.Compose(shellSettings, shellDescriptor); // Initialize database explicitly, and store shell descriptor. using (var bootstrapLifetimeScope = _shellContainerFactory.CreateContainer(shellSettings, shellBlueprint)) { using (var environment = bootstrapLifetimeScope.CreateWorkContextScope()) { // Check if the database is already created (in case an exception occured in the second phase). var schemaBuilder = new SchemaBuilder(environment.Resolve <IDataMigrationInterpreter>()); var installationPresent = true; try { var tablePrefix = String.IsNullOrEmpty(shellSettings.DataTablePrefix) ? "" : shellSettings.DataTablePrefix + "_"; schemaBuilder.ExecuteSql("SELECT * FROM " + tablePrefix + "Settings_ShellDescriptorRecord"); } catch { installationPresent = false; } if (installationPresent) { throw new OrchardException(T("A previous Orchard installation was detected in this database with this table prefix.")); } // Workaround to avoid some Transaction issue for PostgreSQL. environment.Resolve <ITransactionManager>().RequireNew(); schemaBuilder.CreateTable("Orchard_Framework_DataMigrationRecord", table => table .Column <int>("Id", column => column.PrimaryKey().Identity()) .Column <string>("DataMigrationClass") .Column <int>("Version")); schemaBuilder.AlterTable("Orchard_Framework_DataMigrationRecord", table => table.AddUniqueConstraint("UC_DMR_DataMigrationClass_Version", "DataMigrationClass", "Version")); var dataMigrationManager = environment.Resolve <IDataMigrationManager>(); dataMigrationManager.Update("Settings"); foreach (var feature in context.EnabledFeatures) { dataMigrationManager.Update(feature); } environment.Resolve <IShellDescriptorManager>().UpdateShellDescriptor( 0, shellDescriptor.Features, shellDescriptor.Parameters); } } // In effect "pump messages" see PostMessage circa 1980. while (_processingEngine.AreTasksPending()) { _processingEngine.ExecuteNextTask(); } // Creating a standalone environment. // in theory this environment can be used to resolve any normal components by interface, and those // components will exist entirely in isolation - no crossover between the safemode container currently in effect. using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) { try { executionId = CreateTenantData(context, environment); } catch { environment.Resolve <ITransactionManager>().Cancel(); throw; } } _shellSettingsManager.SaveSettings(shellSettings); return(executionId); }