/// <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>(), }); }
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>(), }); }
/// <summary> /// 创建 Shell 运行时上下文。 /// </summary> /// <returns>创建的 <see cref="ShellContext"/> 实例。</returns> public ShellContext CreateShellContext() { _logger.WriteTrace($"正在为应用程序 {_options.AppName}({_options.AppSystemName}) 创建 Shell 。"); var knownDescriptor = _shellDescriptorCache.Fetch(_options.AppName); if (knownDescriptor == null) { //本地没有存储蓝图信息,则先构建应用程序运行所需的最小蓝图。 _logger.WriteTrace("找不到缓存的 SehllDescriptor 对象。将使用最小蓝图启动应用程序。"); knownDescriptor = MinimumShellDescriptor(); } //组装应用程序组件构建蓝图。 var blueprint = _compositionStrategy.Compose(_options.AppName, knownDescriptor); ShellDescriptor currentDescriptor = _shellDescriptorManager.GetShellDescriptor(); //首次运行 currentDescriptor 可能为空,将用最小蓝图启动程序。 if (currentDescriptor != null && knownDescriptor.ApplicationName != currentDescriptor.ApplicationName) { _logger.WriteTrace("获得了新的 Shell 信息。 正在重新创建 Shell 蓝图。"); _shellDescriptorCache.Store(_options.AppName, currentDescriptor); blueprint = _compositionStrategy.Compose(_options.AppName, currentDescriptor); } //注意,ConfigureBlueprint 为迭代器方法,对属性赋值时切勿直接赋值,应该先保证调用。 //迭代器方法在实际使用时才会调用,更多请参考 C# 语言知识,这里先 ToArray 防止访问 ShellContext.Services 属性时造成多次调用。 var descriptor = this.BuildDependencies(blueprint); return(new ShellContext { Descriptor = currentDescriptor ?? knownDescriptor, Blueprint = blueprint, Services = descriptor.Item1, EventSubscriptors = descriptor.Item2 }); }
/// <summary> /// 获取当前外壳描述符。 /// </summary> /// <returns>外壳描述符。</returns> public ShellDescriptor GetShellDescriptor() { //得到当前租户的外壳描述符。 var descriptor = _shellDescriptorCache.Fetch(_settings.Name); //如果之前的记录与最新的功能描述符相等直接返回。 if (descriptor != null) { return(descriptor); } //得到最新的功能描述符名称集合。 var features = GetFeatures(); //添加一个新的描述符。 return(new ShellDescriptor { Features = features.Select(i => new ShellFeature { Name = i }).ToArray(), SerialNumber = GetSerialNumber() }); }
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>(), }); }