/// <summary> /// Constructs data-sources /// </summary> /// <param name="datasourceNodes"></param> /// <param name="tracker"></param> public static void ConstructDataSources(List <XmlNode> datasourceNodes, Action <string, Exception> tracker = null) => RepositoryMediator.ConstructDataSources(datasourceNodes, tracker);
/// <summary> /// Initializes all types in assemblies /// </summary> /// <param name="assemblies">The collection of assemblies</param> /// <param name="tracker">The tracker for tracking logs</param> /// <param name="updateFromConfigurationFile">true to update other settings from configuration file on the disc</param> /// <param name="config">The XML node that contains configuration</param> public static void Initialize(IEnumerable <Assembly> assemblies, Action <string, Exception> tracker = null, bool updateFromConfigurationFile = true, XmlNode config = null) { tracker?.Invoke($"Start to initialize repositories & entities [{assemblies.Select(a => a.GetName().Name).ToString(", ")}]", null); if (tracker == null && RepositoryMediator.IsDebugEnabled) { RepositoryMediator.WriteLogs($"Start to initialize repositories & entities [{assemblies.Select(a => a.GetName().Name).ToString(", ")}]"); } // initialize & register all types assemblies.ForEach(assembly => RepositoryStarter.Initialize(assembly, tracker)); // read configuration if (updateFromConfigurationFile && config == null) { if (ConfigurationManager.GetSection(UtilityService.GetAppSetting("Section:Repositories", "net.vieapps.repositories")) is AppConfigurationSectionHandler configSection) { config = configSection.Section; } if (config == null) { throw new ConfigurationErrorsException("Cannot find the configuration section (might be named as 'net.vieapps.repositories') in the configuration file"); } } // update configuration if (config != null) { try { // update settings of data sources if (config.SelectNodes("dataSources/dataSource") is XmlNodeList dataSourceNodes) { RepositoryMediator.ConstructDataSources(dataSourceNodes.ToList(), tracker); } // update settings of repositories if (updateFromConfigurationFile && config.SelectNodes("repository") is XmlNodeList repositoryNodes) { repositoryNodes.ToList().ForEach(repositoryNode => { // update repository var settingsJson = repositoryNode.ToJson(); tracker?.Invoke($"Update settings of a repository => {settingsJson}", null); if (tracker == null && RepositoryMediator.IsDebugEnabled) { RepositoryMediator.WriteLogs($"Update settings of a repository => {settingsJson}"); } RepositoryDefinition.Update(settingsJson, tracker); // update repository entities if (repositoryNode.SelectNodes("entity") is XmlNodeList entityNodes) { entityNodes.ToList().ForEach(repositoryEntityNode => { settingsJson = repositoryEntityNode.ToJson(); tracker?.Invoke($"Update settings of a repository entity => {settingsJson}", null); if (tracker == null && RepositoryMediator.IsDebugEnabled) { RepositoryMediator.WriteLogs($"Update settings of a repository entity => {settingsJson}"); } EntityDefinition.Update(settingsJson, tracker); }); } }); } // default data sources RepositoryMediator.DefaultVersionDataSourceName = config.Attributes["versionDataSource"]?.Value; RepositoryMediator.DefaultTrashDataSourceName = config.Attributes["trashDataSource"]?.Value; // ensure schemas (SQL) if ("true".IsEquals(config.Attributes["ensureSchemas"]?.Value)) { Task.Run(async() => await RepositoryMediator.EntityDefinitions.ForEachAsync(async(definition, cancellationToken) => { var primaryDataSource = RepositoryMediator.GetPrimaryDataSource(null, definition); primaryDataSource = primaryDataSource != null && primaryDataSource.Mode.Equals(RepositoryMode.SQL) ? primaryDataSource : null; await RepositoryStarter.EnsureSqlSchemasAsync(definition, primaryDataSource, tracker, cancellationToken).ConfigureAwait(false); var secondaryDataSource = RepositoryMediator.GetSecondaryDataSource(null, definition); secondaryDataSource = secondaryDataSource != null && secondaryDataSource.Mode.Equals(RepositoryMode.SQL) ? secondaryDataSource : null; await RepositoryStarter.EnsureSqlSchemasAsync(definition, secondaryDataSource, tracker, cancellationToken).ConfigureAwait(false); await RepositoryMediator.GetSyncDataSources(null, definition) .Where(dataSource => dataSource.Mode.Equals(RepositoryMode.SQL) && !dataSource.Name.IsEquals(primaryDataSource?.Name) && !dataSource.Name.IsEquals(secondaryDataSource?.Name)) .ForEachAsync(async(dataSource, token) => await RepositoryStarter.EnsureSqlSchemasAsync(definition, dataSource, tracker, token).ConfigureAwait(false), cancellationToken, true, false) .ConfigureAwait(false); }, CancellationToken.None, true, false)).ConfigureAwait(false); } // ensure indexes (NoSQL) if ("true".IsEquals(config.Attributes["ensureIndexes"]?.Value)) { Task.Run(async() => await RepositoryMediator.EntityDefinitions.ForEachAsync(async(definition, cancellationToken) => { var primaryDataSource = RepositoryMediator.GetPrimaryDataSource(null, definition); primaryDataSource = primaryDataSource != null && primaryDataSource.Mode.Equals(RepositoryMode.NoSQL) ? primaryDataSource : null; await RepositoryStarter.EnsureNoSqlIndexesAsync(definition, primaryDataSource, tracker, cancellationToken).ConfigureAwait(false); var secondaryDataSource = RepositoryMediator.GetSecondaryDataSource(null, definition); secondaryDataSource = secondaryDataSource != null && secondaryDataSource.Mode.Equals(RepositoryMode.NoSQL) ? secondaryDataSource : null; await RepositoryStarter.EnsureNoSqlIndexesAsync(definition, secondaryDataSource, tracker, cancellationToken).ConfigureAwait(false); await RepositoryMediator.GetSyncDataSources(null, definition) .Where(dataSource => dataSource.Mode.Equals(RepositoryMode.NoSQL) && !dataSource.Name.IsEquals(primaryDataSource?.Name) && !dataSource.Name.IsEquals(secondaryDataSource?.Name)) .ForEachAsync(async(dataSource, token) => await RepositoryStarter.EnsureNoSqlIndexesAsync(definition, dataSource, tracker, token).ConfigureAwait(false), cancellationToken, true, false) .ConfigureAwait(false); }, CancellationToken.None, true, false)).ConfigureAwait(false); } } catch (Exception ex) { tracker?.Invoke($"Error occurred while updating the repository => {ex.Message}", ex); if (tracker == null) { RepositoryMediator.WriteLogs($"Error occurred while updating the repository => {ex.Message}", ex); } throw; } } else { tracker?.Invoke("No configuration to update", null); if (tracker == null && RepositoryMediator.IsDebugEnabled) { RepositoryMediator.WriteLogs("No configuration to update"); } } tracker?.Invoke($"Total of registered repositories: {RepositoryMediator.RepositoryDefinitions.Count}", null); tracker?.Invoke($"Total of registered repository entities: {RepositoryMediator.EntityDefinitions.Count}", null); tracker?.Invoke($"Total of registered event-handlers: {RepositoryMediator.EventHandlers.Count}", null); tracker?.Invoke($"Total of registered data-sources: {RepositoryMediator.DataSources.Count}", null); tracker?.Invoke($"Default data-source for storing version contents: {RepositoryMediator.DefaultVersionDataSourceName ?? "(None)"}", null); tracker?.Invoke($"Default data-source for storing trash contents: {RepositoryMediator.DefaultTrashDataSourceName ?? "(None)"}", null); if (tracker == null && RepositoryMediator.IsDebugEnabled) { RepositoryMediator.WriteLogs($"Total of registered repositories: {RepositoryMediator.RepositoryDefinitions.Count}", null); RepositoryMediator.WriteLogs($"Total of registered repository entities: {RepositoryMediator.EntityDefinitions.Count}", null); RepositoryMediator.WriteLogs($"Total of registered event-handlers: {RepositoryMediator.EventHandlers.Count}", null); RepositoryMediator.WriteLogs($"Total of registered data-sources: {RepositoryMediator.DataSources.Count}", null); RepositoryMediator.WriteLogs($"Default data-source for storing version contents: {RepositoryMediator.DefaultVersionDataSourceName ?? "(None)"}", null); RepositoryMediator.WriteLogs($"Default data-source for storing trash contents: {RepositoryMediator.DefaultTrashDataSourceName ?? "(None)"}", null); } }