/// <summary> /// 外壳设置保存成功之后。 /// </summary> /// <param name="settings">外壳设置信息。</param> public void Saved(ShellSettings settings) { lock (NeedMigratorTenants) { if (!NeedMigratorTenants.Contains(settings.Name)) NeedMigratorTenants.Add(settings.Name); } }
public DataMigratorService(IEnumerable<IMigratorDataServicesProvider> migratorDataServicesProviders, IEnumerable<IMigration> migrations, ILifetimeScope lifetimeScope, ShellSettings shellSettings) { _migratorDataServicesProviders = migratorDataServicesProviders; _migrations = migrations; _lifetimeScope = lifetimeScope; _shellSettings = shellSettings; Logger = NullLogger.Instance; }
/// <summary> /// 初始化一个表单授权服务。 /// </summary> /// <param name="settings">租户设置。</param> /// <param name="clock">时钟服务。</param> /// <param name="httpContextAccessor">HttpContext访问器。</param> protected FormsAuthenticationServiceBase(ShellSettings settings, IClock clock, IHttpContextAccessor httpContextAccessor) { _settings = settings; _clock = clock; _httpContextAccessor = httpContextAccessor; Logger = NullLogger.Instance; ExpirationTimeSpan = TimeSpan.FromDays(30); }
public DefaultRoutePublisher(RouteCollection routeCollection, ShellSettings shellSettings, IExtensionManager extensionManager, IWebWorkContextAccessor webWorkContextAccessor, IRunningShellTable runningShellTable, IEnumerable<IRoutePublisherEventHandler> routePublisherEventHandlers) { _routeCollection = routeCollection; _shellSettings = shellSettings; _extensionManager = extensionManager; _webWorkContextAccessor = webWorkContextAccessor; _runningShellTable = runningShellTable; _routePublisherEventHandlers = routePublisherEventHandlers; }
public DefaultLocalizedStringManager(IVirtualPathProvider virtualPathProvider, IVirtualPathMonitor virtualPathMonitor, IExtensionManager extensionManager, ICacheManager cacheManager, ShellSettings shellSettings, ISignals signals) { _virtualPathProvider = virtualPathProvider; _virtualPathMonitor = virtualPathMonitor; _extensionManager = extensionManager; _cacheManager = cacheManager; _shellSettings = shellSettings; _signals = signals; Logger = NullLogger.Instance; }
public ShellRoute(RouteBase route, ShellSettings shellSettings, IWebWorkContextAccessor workContextAccessor, IRunningShellTable runningShellTable) { _route = route; _shellSettings = shellSettings; _runningShellTable = runningShellTable; _workContextAccessor = workContextAccessor; if (!string.IsNullOrEmpty(_shellSettings.GetRequestUrlPrefix())) _urlPrefix = new UrlPrefix(_shellSettings.GetRequestUrlPrefix()); Area = route.GetAreaName(); }
/// <summary> /// 外壳设置保存成功之后。 /// </summary> /// <param name="settings">外壳设置信息。</param> public void Saved(ShellSettings settings) { if (!DataMigratorsBuilderExtensions.StartingExecute) return; lock (NeedMigratorTenants) { if (!NeedMigratorTenants.Contains(settings.Name)) NeedMigratorTenants.Add(settings.Name); } }
public DefaultShellDescriptorManager(IExtensionManager extensionManager, IEnumerable<IShellDescriptorManagerEventHandler> events, ShellSettings settings, IApplicationFolder applicationFolder) { _extensionManager = extensionManager; _events = events; _settings = settings; List.Init("~/App_Data/descriptors.dat", applicationFolder); var descriptor = List.OrderByDescending(i => i.SerialNumber).FirstOrDefault(); _serialNumber = descriptor == null ? 0 : descriptor.SerialNumber; T = NullLocalizer.Instance; }
private static RecordBlueprint BuildRecord(Type type, Feature feature, ShellSettings settings) { var extensionDescriptor = feature.Descriptor.Extension; var extensionName = extensionDescriptor.Id.Replace('.', '_'); var dataTablePrefix = string.Empty; if (!string.IsNullOrEmpty(settings.GetDataTablePrefix())) dataTablePrefix = settings.GetDataTablePrefix() + "_"; return new RecordBlueprint { Type = type, Feature = feature, TableName = dataTablePrefix + extensionName + '_' + type.Name, }; }
/// <summary> /// 添加。 /// </summary> /// <param name="settings">外壳设置。</param> public void Add(ShellSettings settings) { _lock.EnterWriteLock(); try { _shells = _shells .Where(s => s.Name != settings.Name) .Concat(new[] { settings }) .ToArray(); Organize(); } finally { _lock.ExitWriteLock(); } }
public void ActivateShell(ShellSettings settings) { Logger.Debug("准备激活外壳: " + settings.Name); //寻找相关的外壳上下文 var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name); if (shellContext == null && settings.State == TenantState.Disabled) return; if (shellContext == null || settings.State == TenantState.Uninitialized) { //创建外壳 var context = CreateShellContext(settings); //激活外壳 ActivateShell(context); } //租户被禁用则终止外壳 else if (settings.State == TenantState.Disabled) { shellContext.Shell.Terminate(); shellContext.Container.Dispose(); _runningShellTable.Remove(settings); _shellContexts = _shellContexts.Where(shell => shell.Settings.Name != settings.Name); } //重新加载因为外壳设置被变更的外壳 else { //释放之前的外壳上下文 shellContext.Shell.Terminate(); shellContext.Container.Dispose(); var context = _shellContextFactory.CreateShellContext(settings); //激活并注册已修改的外壳上下文 _shellContexts = _shellContexts.Where(shell => shell.Settings.Name != settings.Name).Union(new[] { context }); context.Shell.Activate(); _runningShellTable.Update(settings); } }
/// <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>(), }; }
/// <summary> /// 执行命令。 /// </summary> /// <param name="context">命令执行上下文。</param> public override void Execute(CommandExecuteContext context) { var settings = SettingsManager.LoadSettings().FirstOrDefault(i => string.Equals(i.Name, TenantName, StringComparison.OrdinalIgnoreCase)); var isAdd = settings == null; if (settings != null && !Quiet) { context.WriteLine("已经存在名称为 '{0}' 的租户,确定要替换吗?\t输入'Y'继续执行,输入其他则终止执行。", TenantName); var t = context.Read("y"); if (!t.Equals("y", StringComparison.OrdinalIgnoreCase)) return; } else settings = new ShellSettings(); if (List != null) { foreach (var temp in List.Where(i => !string.IsNullOrWhiteSpace(i))) { var index = temp.IndexOf("=", StringComparison.Ordinal); if (index == -1) continue; var key = temp.Substring(0, index).Escape(); var value = temp.Substring(index); if (value.StartsWith("=")) value = value.Remove(0, 1); if (string.IsNullOrWhiteSpace(value)) continue; value = value.Escape(); settings[key] = value.Escape(); } } settings.Name = TenantName; settings.State = State; SettingsManager.SaveSettings(settings); context.WriteLine("{0}租户 '{1}' 成功。", isAdd ? "添加" : "修改", TenantName); }
/// <summary> /// 创建一个独立的环境。 /// </summary> /// <param name="shellSettings">外壳设置。</param> /// <returns>工作上下文范围。</returns> IWorkContextScope IHost.CreateStandaloneEnvironment(ShellSettings shellSettings) { Logger.Debug("为租户 {0} 创建独立的环境。", shellSettings.Name); MonitorExtensions(); BuildCurrent(); var shellContext = CreateShellContext(shellSettings); return shellContext.Container.CreateWorkContextScope(); }
/// <summary> /// 获取一个外壳上下文。 /// </summary> /// <param name="shellSettings">外壳设置。</param> /// <returns>外壳上下文。</returns> public ShellContext GetShellContext(ShellSettings shellSettings) { return BuildCurrent().SingleOrDefault(shellContext => shellContext.Settings.Name.Equals(shellSettings.Name, StringComparison.OrdinalIgnoreCase)); }
private ShellContext CreateShellContext(ShellSettings settings) { Logger.Debug("为租户 {0} 创建外壳上下文", settings.Name); return _shellContextFactory.CreateShellContext(settings); }
/// <summary> /// 外壳设置保存成功之后。 /// </summary> /// <param name="settings">外壳设置信息。</param> void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) { Logger.Debug("外壳 {0} 被保存 ", settings.Name); if (settings.State == TenantState.Invalid) return; if (_tenantsToRestart.GetState().Any(t => t.Name.Equals(settings.Name))) return; Logger.Debug("标识租户: {0} {1} 需要重启", settings.Name, settings.State); _tenantsToRestart.GetState().Add(settings); }
/// <summary> /// 外壳设置保存成功之后。 /// </summary> /// <param name="settings">外壳设置信息。</param> public void Saved(ShellSettings settings) { _eventIsRun = true; }
public TenantThemeSelector(ShellSettings settings) { _settings = settings; }
public EntityFrameworkDbContextFactory(IServiceTypeHarvester serviceTypeHarvester, IEnumerable<IEntityFrameworkDataServicesProvider> dataServicesProviders, IEnumerable<IMapping> mappings, ShellBlueprint shellBlueprint) { _serviceTypeHarvester = serviceTypeHarvester; _dataServicesProviders = dataServicesProviders; _mappings = mappings; _recordBlueprints = shellBlueprint.GetRecords(); _shellSettings = shellBlueprint.Settings; Logger = NullLogger.Instance; }
private DbCompiledModel GetDbCompiledModel(ShellSettings shellSettings) { if (DbCompiledModelCacheDictionary.ContainsKey(shellSettings.Name)) return DbCompiledModelCacheDictionary[shellSettings.Name]; var records = _recordBlueprints.ToArray(); var modelBuilder = new DbModelBuilder(); //设置数据库架构名称。 // modelBuilder.HasDefaultSchema(shellSettings.Name); //将记录类型添加至DbContext。 foreach (var recordBlueprint in records) Entity(recordBlueprint.Type, modelBuilder); //默认配置信息。 modelBuilder.Types().Configure(config => { var record = records.FirstOrDefault(i => i.Type == config.ClrType); if (record == null) return; config.ToTable(record.TableName); }); //应用约定。 modelBuilder.Conventions.Add(GetConventions()); var dataServiceProvider = GetDataServicesProvider(shellSettings); var connectionString = shellSettings.GetDataConnectionString(); string providerManifestToken; using (var connection = dataServiceProvider.CreateConnection(connectionString)) providerManifestToken = dataServiceProvider.Instance.GetProviderManifestToken(connection); var dbProviderInfo = new DbProviderInfo(dataServiceProvider.ProviderInvariantName, providerManifestToken); var dbModel = modelBuilder.Build(dbProviderInfo); return dbModel.Compile(); }
public DefaultTenantService(ShellSettings shellSettings, ICacheManager cacheManager) { _shellSettings = shellSettings; _cacheManager = cacheManager; }
/// <summary> /// 获取一个外壳上下文。 /// </summary> /// <param name="shellSettings">外壳设置。</param> /// <returns>外壳上下文。</returns> public ShellContext GetShellContext(ShellSettings shellSettings) { return BuildCurrent().SingleOrDefault(shellContext => shellContext.Settings.Name.Equals(shellSettings.Name)); }
public DefaultEncryptionService(ShellSettings shellSettings) { _shellSettings = shellSettings; }
/// <summary> /// 初始化一个新的外壳设置。 /// </summary> /// <param name="settings">外壳设置。</param> public ShellSettings(ShellSettings settings) : this() { foreach (var item in settings.Keys) this[item] = settings[item]; }
private IEntityFrameworkDataServicesProvider GetDataServicesProvider(ShellSettings shellSettings) { var providerName = shellSettings.GetDataProvider(); if (string.IsNullOrWhiteSpace(providerName)) throw new ArgumentException("因为数据服务提供名称为空,所以无法确定数据服务提供者。"); var provider = _dataServicesProviders.FirstOrDefault( p => string.Equals(p.ProviderName, providerName, StringComparison.OrdinalIgnoreCase)); if (provider == null) throw new NotSupportedException(string.Format("找不到名称为:{0}的数据服务提供程序。", providerName)); return provider; }
/// <summary> /// 初始化一个表单授权服务。 /// </summary> /// <param name="settings">租户设置。</param><param name="clock">时钟服务。</param><param name="httpContextAccessor">HttpContext访问器。</param> public FormsAuthenticationService(ShellSettings settings, IClock clock, IHttpContextAccessor httpContextAccessor) : base(settings, clock, httpContextAccessor) { }
public DbConnectionFactory(ShellSettings shellSettings, IEnumerable<IDbConnectionProvider> providers) { _shellSettings = shellSettings; _providers = providers; }
/// <summary> /// 创建一个外壳容器。 /// </summary> /// <param name="settings">外壳设置。</param> /// <param name="blueprint">外壳蓝图。</param> /// <returns>外壳容器。</returns> public ILifetimeScope CreateContainer(ShellSettings settings, ShellBlueprint blueprint) { var intermediateScope = _lifetimeScope.BeginLifetimeScope( builder => { //TODO:CollectionOrderModule、CacheModule 等Module是公共的,需要验证 Root 范围注册了子级生命范围是否生效,如果生效则在外壳容器中忽略掉这些Module foreach (var item in blueprint.Dependencies.Where(t => typeof(IModule).IsAssignableFrom(t.Type))) { RegisterType(builder, item) .Keyed<IModule>(item.Type) .InstancePerDependency(); } }); return intermediateScope.BeginLifetimeScope( "shell", builder => { builder.Register(ctx => settings); builder.Register(ctx => blueprint.Descriptor); builder.Register(ctx => blueprint); var moduleIndex = intermediateScope.Resolve<IIndex<Type, IModule>>(); foreach (var item in blueprint.Dependencies.Where(t => typeof(IModule).IsAssignableFrom(t.Type))) { builder.RegisterModule(moduleIndex[item.Type]); } foreach (var item in blueprint.Dependencies.Where(t => typeof(IDependency).IsAssignableFrom(t.Type))) { var registration = RegisterType(builder, item) .InstancePerLifetimeScope(); foreach (var interfaceType in item.Type.GetInterfaces() .Where(itf => typeof(IDependency).IsAssignableFrom(itf) && !typeof(IEventHandler).IsAssignableFrom(itf))) { registration = registration.As(interfaceType); if (typeof(ISingletonDependency).IsAssignableFrom(interfaceType)) { registration = registration.InstancePerMatchingLifetimeScope("shell"); } else if (typeof(IUnitOfWorkDependency).IsAssignableFrom(interfaceType)) { registration = registration.InstancePerMatchingLifetimeScope("work"); } else if (typeof(ITransientDependency).IsAssignableFrom(interfaceType)) { registration = registration.InstancePerDependency(); } } if (!typeof(IEventHandler).IsAssignableFrom(item.Type)) continue; var interfaces = item.Type.GetInterfaces(); foreach (var interfaceType in interfaces) { if (interfaceType.GetInterface(typeof(IEventHandler).Name) != null) { registration = registration.Named<IEventHandler>(interfaceType.Name); } } } _shellContainerRegistrationses.Invoke(i => i.Registrations(builder, blueprint), NullLogger.Instance); }); }
private void Organize() { var qualified = _shells.Where(x => !string.IsNullOrEmpty(x.GetRequestUrlHost()) || !string.IsNullOrEmpty(x.GetRequestUrlPrefix())); var unqualified = _shells .Where(x => string.IsNullOrEmpty(x.GetRequestUrlHost()) && string.IsNullOrEmpty(x.GetRequestUrlPrefix())) .ToList(); _shellsByHost = qualified .SelectMany(s => s.GetRequestUrlHost() == null || s.GetRequestUrlHost().IndexOf(',') == -1 ? new[] { s } : s.GetRequestUrlHost().Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(h => { var settings = new ShellSettings(s); settings.SetRequestUrlHost(h); return settings; })) .GroupBy(s => s.GetRequestUrlHost() ?? string.Empty) .OrderByDescending(g => g.Key.Length) .ToDictionary(x => x.Key, x => x.AsEnumerable(), StringComparer.OrdinalIgnoreCase); if (unqualified.Count() == 1) { _fallback = unqualified.Single(); } else if (unqualified.Any()) { _fallback = unqualified.SingleOrDefault(x => x.Name == ShellSettings.DefaultName); } else { _fallback = null; } _shellsByHostAndPrefix.Clear(); }