/// <summary>
        /// Creates an engine with the specified application state, configuration, and service provider.
        /// </summary>
        /// <param name="applicationState">The state of the application (or <c>null</c> for an empty application state).</param>
        /// <param name="serviceCollection">The service collection (or <c>null</c> for an empty default service collection).</param>
        /// <param name="configuration">The application configuration.</param>
        /// <param name="settings">Settings that should override configuration values.</param>
        /// <param name="classCatalog">A class catalog of all assemblies in scope.</param>
        public Engine(
            ApplicationState applicationState,
            IServiceCollection serviceCollection,
            IConfiguration configuration,
            IEnumerable <KeyValuePair <string, object> > settings,
            ClassCatalog classCatalog)
        {
            _pipelines       = new PipelineCollection(this);
            ApplicationState = applicationState ?? new ApplicationState(null, null, null);
            ClassCatalog     = classCatalog ?? new ClassCatalog();
            ClassCatalog.Populate();
            ScriptHelper = new ScriptHelper(this);
            Settings     = new ConfigurationSettings(
                this,
                configuration ?? new ConfigurationRoot(Array.Empty <IConfigurationProvider>()),
                settings);
            _serviceScope             = GetServiceScope(serviceCollection);
            _logger                   = Services.GetRequiredService <ILogger <Engine> >();
            DocumentFactory           = new DocumentFactory(this, Settings);
            _diagnosticsTraceListener = new DiagnosticsTraceListener(_logger);
            System.Diagnostics.Trace.Listeners.Add(_diagnosticsTraceListener);

            // Add the service-based pipelines as late as possible so other services have been configured
            AddServicePipelines();
        }
Exemple #2
0
 /// <summary>
 /// Creates an engine with the specified application state and service provider.
 /// </summary>
 /// <param name="applicationState">The state of the application (or <c>null</c> for an empty application state).</param>
 /// <param name="configuration">The application configuration.</param>
 /// <param name="serviceCollection">The service collection (or <c>null</c> for an empty default service collection).</param>
 public Engine(ApplicationState applicationState, IConfiguration configuration, IServiceCollection serviceCollection)
 {
     _pipelines                = new PipelineCollection(this);
     ApplicationState          = applicationState ?? new ApplicationState(null, null, null);
     Settings                  = new EngineSettings(configuration ?? new ConfigurationRoot(Array.Empty <IConfigurationProvider>()));
     _serviceScope             = GetServiceScope(serviceCollection);
     _logger                   = Services.GetRequiredService <ILogger <Engine> >();
     DocumentFactory           = new DocumentFactory(Settings);
     _diagnosticsTraceListener = new DiagnosticsTraceListener(_logger);
     System.Diagnostics.Trace.Listeners.Add(_diagnosticsTraceListener);
 }
        /// <summary>
        /// Creates an engine with the specified application state, configuration, and service provider.
        /// </summary>
        /// <param name="applicationState">The state of the application (or <c>null</c> for an empty application state).</param>
        /// <param name="serviceCollection">The service collection (or <c>null</c> for an empty default service collection).</param>
        /// <param name="configurationOverrides">Values that should override configuration values.</param>
        /// <param name="configuration">The application configuration.</param>
        public Engine(ApplicationState applicationState, IServiceCollection serviceCollection, IConfiguration configuration, IDictionary <string, object> configurationOverrides)
        {
            _pipelines       = new PipelineCollection(this);
            ApplicationState = applicationState ?? new ApplicationState(null, null, null);
            ScriptHelper     = new ScriptHelper(this);
            Settings         = new ReadOnlyConfigurationSettings(
                this,
                configuration ?? new ConfigurationRoot(Array.Empty <IConfigurationProvider>()),
                configurationOverrides);
            _serviceScope             = GetServiceScope(serviceCollection);
            _logger                   = Services.GetRequiredService <ILogger <Engine> >();
            DocumentFactory           = new DocumentFactory(this, Settings);
            _diagnosticsTraceListener = new DiagnosticsTraceListener(_logger);
            System.Diagnostics.Trace.Listeners.Add(_diagnosticsTraceListener);

            // Add the service-based pipelines as late as possible so other services have been configured
            AddServicePipelines();
        }
Exemple #4
0
        // The result array is sorted based on dependencies
        private static PipelinePhase[] GetPipelinePhases(PipelineCollection pipelines, ILogger logger)
        {
            // Perform a topological sort to create phases down the dependency tree
            Dictionary <string, PipelinePhases> phases = new Dictionary <string, PipelinePhases>(StringComparer.OrdinalIgnoreCase);
            List <PipelinePhases> sortedPhases         = new List <PipelinePhases>();
            HashSet <string>      visited = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (KeyValuePair <string, IPipeline> pipelineEntry in pipelines)
            {
                Visit(pipelineEntry.Key, pipelineEntry.Value);
            }

            // Make a pass through non-isolated transform phases to set dependencies to all non-isolated process phases
            foreach (PipelinePhases pipelinePhases in phases.Values.Where(x => !x.Isolated))
            {
                pipelinePhases.Transform.Dependencies =
                    pipelinePhases.Transform.Dependencies
                    .Concat(phases.Values.Where(x => x != pipelinePhases && !x.Isolated).Select(x => x.Process))
                    .ToArray();
            }

            return(sortedPhases
                   .Select(x => x.Input)
                   .Concat(sortedPhases.Select(x => x.Process))
                   .Concat(sortedPhases.Select(x => x.Transform))
                   .Concat(sortedPhases.Select(x => x.Output))
                   .ToArray());

            // Returns the process phases (if not isolated)
            PipelinePhases Visit(string name, IPipeline pipeline)
            {
                PipelinePhases pipelinePhases;

                if (pipeline.Isolated)
                {
                    // This is an isolated pipeline so just add the phases in a chain
                    pipelinePhases           = new PipelinePhases(true);
                    pipelinePhases.Input     = new PipelinePhase(pipeline, name, Phase.Input, pipeline.InputModules, logger);
                    pipelinePhases.Process   = new PipelinePhase(pipeline, name, Phase.Process, pipeline.ProcessModules, logger, pipelinePhases.Input);
                    pipelinePhases.Transform = new PipelinePhase(pipeline, name, Phase.Transform, pipeline.TransformModules, logger, pipelinePhases.Process);
                    pipelinePhases.Output    = new PipelinePhase(pipeline, name, Phase.Output, pipeline.OutputModules, logger, pipelinePhases.Transform);
                    phases.Add(name, pipelinePhases);
                    sortedPhases.Add(pipelinePhases);
                    return(pipelinePhases);
                }

                if (visited.Add(name))
                {
                    // Visit dependencies if this isn't an isolated pipeline
                    List <PipelinePhase> processDependencies = new List <PipelinePhase>();
                    foreach (string dependencyName in pipeline.Dependencies)
                    {
                        if (!pipelines.TryGetValue(dependencyName, out IPipeline dependency))
                        {
                            throw new Exception($"Could not find pipeline dependency {dependencyName} of {name}");
                        }
                        if (dependency.Isolated)
                        {
                            throw new Exception($"Pipeline {name} has dependency on isolated pipeline {dependencyName}");
                        }
                        processDependencies.Add(Visit(dependencyName, dependency).Process);
                    }

                    // Add the phases (by this time all dependencies should have been added)
                    pipelinePhases       = new PipelinePhases(false);
                    pipelinePhases.Input = new PipelinePhase(pipeline, name, Phase.Input, pipeline.InputModules, logger);
                    processDependencies.Insert(0, pipelinePhases.Input);                                                                                      // Makes sure the process phase is also dependent on it's input phase
                    pipelinePhases.Process   = new PipelinePhase(pipeline, name, Phase.Process, pipeline.ProcessModules, logger, processDependencies.ToArray());
                    pipelinePhases.Transform = new PipelinePhase(pipeline, name, Phase.Transform, pipeline.TransformModules, logger, pipelinePhases.Process); // Transform dependencies will be added after all pipelines have been processed
                    pipelinePhases.Output    = new PipelinePhase(pipeline, name, Phase.Output, pipeline.OutputModules, logger, pipelinePhases.Transform);
                    phases.Add(name, pipelinePhases);
                    sortedPhases.Add(pipelinePhases);
                }
                else if (!phases.TryGetValue(name, out pipelinePhases))
                {
                    throw new Exception($"Pipeline cyclical dependency detected involving {name}");
                }

                return(pipelinePhases);
            }
        }